当前位置: 首页 > news >正文

基于dcmtk的dicom工具 第八章 echoSCU-dicom测试连接

系列文章目录


文章目录

  • 系列文章目录
  • 前言
  • 一、echoSCU工程流程
  • 二、代码


前言

第六章 StoreSCU-图像发送 和 第七章 FindSCU-查询工作列表两篇文章中都有“测试连接”的功能,
其实现方式都是利用dcmtk实现echoSCU功能。
本章单独介绍echoSCU的工作流程。参考dcmtk 源码echoscu.cc,源文件路径dcmtk-3.6.9\dcmnet\apps\echoscu.cc


一、echoSCU工程流程

dcmtk中SCU的流程大同小异。
注意与
第六章 storescu.cc中的主要流程

第七章 dcmtk findscu主要流程
对比。
前面1~8步的网络协商流程都一样,只有第8步以后处理不同

  1. ASC_initializeNetwork初始化网络
  2. ASC_createAssociationParameters
  3. ASC_setAPTitles
  4. ASC_setTransportLayerType
  5. ASC_setPresentationAddresses
  6. ASC_addPresentationContext
  7. ASC_requestAssociation
  8. ASC_countAcceptedPresentationContexts判断连接是否成功,不成功返回,成功则调用echoSCU测试连接
  9. echoSCU中调用DIMSE_echoUser真正发送连接测试,检测返回是否连接成功
  10. 测试连接完成,释放连接,关闭网络

二、代码

BOOL CWlFindSCU::Echo()
{T_ASC_Network *net;T_ASC_Parameters *params;DIC_NODENAME localHost;DIC_NODENAME peerHost;T_ASC_Association *assoc;OFString temp_str;/* initialize network, i.e. create an instance of T_ASC_Network*. */OFCondition cond = ASC_initializeNetwork(NET_REQUESTOR, 0, 30, &net);if (cond.bad()){DimseCondition::dump(temp_str, cond);Replace(temp_str, _T("\n"), _T("\r\n"));log_error(_T("Init network failed: \n%s"), temp_str.c_str());return FALSE;}/* initialize asscociation parameters, i.e. create an instance of T_ASC_Parameters*. */cond = ASC_createAssociationParameters(&params, ASC_DEFAULTMAXPDU);if (cond.bad()){DimseCondition::dump(temp_str, cond);Replace(temp_str, _T("\n"), _T("\r\n"));log_error(_T("Create Association Parameters Failed: %s"), temp_str.c_str());return FALSE;}/* sets this application's title and the called application's title in the params *//* structure. The default values to be set here are "STORESCU" and "ANY-SCP". */ASC_setAPTitles(params, m_param.localAET.c_str(), m_param.remoteAET.c_str(), NULL);/* Set the transport layer type (type of network connection) in the params *//* strucutre. The default is an insecure connection; where OpenSSL is  *//* available the user is able to request an encrypted,secure connection. */cond = ASC_setTransportLayerType(params, OFFalse);if (cond.bad()){DimseCondition::dump(temp_str, cond);Replace(temp_str, _T("\n"), _T("\r\n"));log_error(_T("Set Transport Layer Type Failed: %s"), temp_str.c_str());return FALSE;}/* Figure out the presentation addresses and copy the *//* corresponding values into the association parameters.*/gethostname(localHost, sizeof(localHost) - 1);sprintf_s(peerHost, "%s:%d", m_param.serverIP.c_str(), m_param.port);ASC_setPresentationAddresses(params, localHost, peerHost);/* Set the presentation contexts which will be negotiated *//* when the network connection will be established */int presentationContextID = 1; /* odd byte value 1, 3, 5, .. 255 */for (unsigned long ii = 0; ii < 1; ii++){cond = ASC_addPresentationContext(params, presentationContextID, UID_VerificationSOPClass,EchotransferSyntaxes, 1);presentationContextID += 2;if (cond.bad()){DimseCondition::dump(temp_str, cond);Replace(temp_str, _T("\n"), _T("\r\n"));log_error(_T("Add Presentation Context Failed: %s"), temp_str.c_str());return FALSE;}}/* dump presentation contexts if required *///OFLOG_DEBUG(echoscuLogger, "Request Parameters:" << OFendl << ASC_dumpParameters(temp_str, params, ASC_ASSOC_RQ));ASC_dumpParameters(temp_str, params, ASC_ASSOC_RQ);Replace(temp_str, _T("\n"), _T("\r\n"));log_debug(_T("Request Parameters:\r\n%s"), temp_str.c_str());/* create association, i.e. try to establish a network connection to another *//* DICOM application. This call creates an instance of T_ASC_Association*. */cond = ASC_requestAssociation(net, params, &assoc);if (cond.bad()){if (cond == DUL_ASSOCIATIONREJECTED){T_ASC_RejectParameters rej;ASC_getRejectParameters(params, &rej);ASC_printRejectParameters(temp_str, &rej);Replace(temp_str, _T("\n"), _T("\r\n"));log_error(_T("Association Rejected:\r\n%s"), temp_str.c_str());return FALSE;}else{DimseCondition::dump(temp_str, cond);Replace(temp_str, _T("\n"), _T("\r\n"));log_error(_T("Association Request Failed: %s"), temp_str.c_str());return FALSE;}}/* dump the presentation contexts which have been accepted/refused */ASC_dumpParameters(temp_str, params, ASC_ASSOC_AC);Replace(temp_str, _T("\n"), _T("\r\n"));log_debug(_T("Association Parameters Negotiated:\r\n%s"), temp_str.c_str());/* count the presentation contexts which have been accepted by the SCP *//* If there are none, finish the execution */if (ASC_countAcceptedPresentationContexts(params) == 0){log_error(_T("No Acceptable Presentation Contexts"));return FALSE;}/* dump general information concerning the establishment of the network connection if required */log_debug(_T("Association Accepted (Max Send PDV: %d)"), assoc->sendPDVLength);/* do the real work, i.e. send a number of C-ECHO-RQ messages to the DICOM application *//* this application is connected with and handle corresponding C-ECHO-RSP messages. */cond = echoSCU(assoc);BOOL bEchoOK = FALSE;if (cond == EC_Normal)bEchoOK = TRUE;/* tear down association, i.e. terminate network connection to SCP */if (cond == EC_Normal){/* release association */log_info(_T("Releasing Association"));log_info(_T("连接成功."));cond = ASC_releaseAssociation(assoc);if (cond.bad()){DimseCondition::dump(temp_str, cond);Replace(temp_str, _T("\n"), _T("\r\n"));log_error(_T("Association Release Failed: %s"), temp_str.c_str());return bEchoOK;}}else if (cond == DUL_PEERREQUESTEDRELEASE){log_error(_T("Protocol Error: Peer requested release (Aborting)"));log_info(_T("连接失败."));cond = ASC_abortAssociation(assoc);if (cond.bad()){DimseCondition::dump(temp_str, cond);Replace(temp_str, _T("\n"), _T("\r\n"));log_error(_T("Association Abort Failed: %s"), temp_str.c_str());return bEchoOK;}}else if (cond == DUL_PEERABORTEDASSOCIATION){log_info(_T("Peer Aborted Association"));log_info(_T("连接失败."));}else{DimseCondition::dump(temp_str, cond);Replace(temp_str, _T("\n"), _T("\r\n"));log_error(_T("Find SCU Failed: %s"), temp_str.c_str());log_info(_T("连接失败."));cond = ASC_abortAssociation(assoc);if (cond.bad()){DimseCondition::dump(temp_str, cond);Replace(temp_str, _T("\n"), _T("\r\n"));log_error(_T("Association Abort Failed: %s"), temp_str.c_str());return bEchoOK;}}/* destroy the association, i.e. free memory of T_ASC_Association* structure. This *//* call is the counterpart of ASC_requestAssociation(...) which was called above. */cond = ASC_destroyAssociation(&assoc);if (cond.bad()){DimseCondition::dump(temp_str, cond);Replace(temp_str, _T("\n"), _T("\r\n"));log_error(_T("destroy association failed: %s"), temp_str.c_str());return bEchoOK;}/* drop the network, i.e. free memory of T_ASC_Network* structure. This call *//* is the counterpart of ASC_initializeNetwork(...) which was called above. */cond = ASC_dropNetwork(&net);if (cond.bad()){DimseCondition::dump(temp_str, cond);Replace(temp_str, _T("\n"), _T("\r\n"));log_error(_T("Drop Network Failed: %s"), temp_str.c_str());return bEchoOK;}return bEchoOK;
}OFCondition CWlFindSCU::echoSCU(T_ASC_Association * assoc)
{DIC_US msgId = assoc->nextMsgID++;DIC_US status;DcmDataset *statusDetail = NULL;/* dump information if required */log_info(_T("Sending Echo Request (MsgID %d)"), msgId);/* send C-ECHO-RQ and handle response */OFCondition cond = DIMSE_echoUser(assoc, msgId, DIMSE_BLOCKING, 0, &status, &statusDetail);/* depending on if a response was received, dump some information */if (cond.good()){log_info(_T("Received Echo Response (%s)"), DU_cechoStatusString(status));}else{OFString temp_str;DimseCondition::dump(temp_str, cond);Replace(temp_str, _T("\n"), _T("\r\n"));log_error(_T("Echo Failed: "), temp_str.c_str());}/* check for status detail information, there should never be any */if (statusDetail != NULL){std::ostringstream ostr;ostr << DcmObject::PrintHelper(*statusDetail);log_debug(_T("Status Detail (should never be any):\r\n"), ostr.str().c_str());delete statusDetail;}/* return result value */return cond;
}
http://www.lryc.cn/news/595015.html

相关文章:

  • Prompt Engineering(提示词工程)基础了解
  • 第三章自定义检视面板_创建自定义编辑器类_编扩展默认组件的显示面板(本章进度6/9)
  • 14.6 《3步实战LLaMA2-7B指令微调:Hugging Face生态+LoRA技术,MT-Bench得分从5.1直升7.3》
  • LeetCode - 3274. Check if Two Chessboard Squares Have the Same Color
  • 数据结构之克鲁斯卡尔算法
  • C#/.NET/.NET Core技术前沿周刊 | 第 47 期(2025年7.14-7.20)
  • Leetcode力扣解题记录--第238题(前/后缀积)
  • OpenCV学习(二)-二维、三维识别
  • 软件工厂 DevSecOps 场景下的测试体系建设实践
  • Facebook 开源多季节性时间序列数据预测工具:Prophet 乘性季节性 Multiplicative Seasonality
  • 昇腾310P软件安装说明
  • Python----NLP自然语言处理(Doc2Vec)
  • 7-Zip 曝出两个可导致拒绝服务的中危漏洞
  • 【网络安全】DDOS攻击
  • (7)ROS2-MUJOCO联合仿真环境迁移优化
  • 网络协议(三)网络层 IPv4、CIDR(使用子网掩码进行网络划分)、NAT在私网划分中的应用
  • 零基础数据结构与算法——第五章:高级算法-回溯算法N皇后问题
  • uniapp+vue3预约时间和日期
  • 布局AI +文化新赛道,浙江省文化产业投资集团赴景联文科技调研交流
  • 算法-比较排序
  • 广播(Broadcast)和组播(Multicast)对比
  • 简单讲解HTTPS如何保证安全性和可靠性
  • https正向代理 GoProxy
  • 计算机发展史:电子管时代的辉煌与局限
  • ubuntu远程桌面不好使
  • Consumer<T>
  • 华为云Stack交付流程
  • cs336 Lecture2
  • iOS打开开发者模式
  • Django Ninja