当前位置: 首页 > 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.dtcms.com/a/291165.html

相关文章:

  • 广东餐饮服务中级水平测试精选题库
  • 基于Python的多传感器融合的障碍物检测与避障演示
  • WPF 项目设置应用程序图标和设置程序集图标
  • 搭建种草商城框架指南
  • 修复WSL安装失败(错误: 0x80248014 )并安装K8S
  • 低空经济展 | 约克科技携小型化测试设备亮相2025深圳eVTOL展
  • Linux物理地址空间入门:从硬件到内核内存的基石
  • Javascript--事件
  • 耐达讯RS232转Ethercat网关:建筑驱动连接的“秘密武器”
  • 【系统全面】Socket编程——基础知识介绍
  • 2x2矩阵教程
  • AI赋能中医传承:智慧医疗新时代解决方案
  • 如何避免redis分布式锁失效
  • 搭建前端页面,介绍对应标签
  • 前端之学习后端java小白(一)之SDKMAN
  • Typecho目录树插件开发:从后端解析到前端渲染全流程
  • AI革命带来的便利
  • [特殊字符] Java反射从入门到飞升:手撕类结构,动态解析一切![特殊字符]
  • 多线程--线程池
  • 【docker】分享一个好用的docker镜像国内站点
  • dev tools的使用
  • FastMCP全篇教程以及解决400 Bad Request和session termination的问题
  • 理解向量及其运算-AI云计算数值分析和代码验证
  • 微店关键词搜索接口深度开发指南
  • 《探索Go语言:云时代的编程新宠》
  • 【WinMerge】怎么一键查找两个文件的内容不同之处? 用它支持一键批量对比!速度贼快~
  • iOS开发 Swift 速记2:三种集合类型 Array Set Dictionary
  • 关于 Python 的踩坑记录
  • 《使用Qt Quick从零构建AI螺丝瑕疵检测系统》——0. 博客系列大纲
  • 多片RFSoC同步,64T 64R