FO-DICOM 实现C-Find + C-Move 客户端SCU 文件传输例子

医疗DICOM开发
620
补充展位
Pages_Weblog_Get#ac2a7539-cf00-46af-be72-45f079bbb3de
文章摘要
此内容由人工摘要内容,并由AI根据文章内容进行润色
暂无内容

DICOM协议下 C#实现 CFind CMove的SCU简单例子

FO-DICOM 实现C-Find + C-Move 客户端SCU 文件传输例子

学习过程中理解到关于 CFind 、CMove 的一些业务逻辑说明 以及实现代码(复制粘贴即可使用),不讲解底层原理,大佬请无视

近期在项目需求有用到 CFind CMove 这两种方式一起的文件传输模式 (老实说觉得挺麻烦的),但该做还是要做的。 因为是第一次接触这种通信方式的项目,看了些网络相关资料,并不复杂,但多数对新人不是很友好 没有相关经验的理解起来比较困难,磕磕绊绊 总算是搞明白了,这里做下记录。

  1. C-Find 释义:可以想象成一个数据查询接口 提交对应查询条件(这个要看服务端查询的实现情况,服务端不支持的条件 加了也没用) 服务端返回给你对应的检查数据集合 (这里以StudyInstanceUID 为返回结果为例) 例子:
static string pacsIp = "127.0.0.1";///测试的服务IP
static int pacsPort = 5678;///测试的服务端口
static string localAe = "YUANTK";///本地的AE
static string remoteAe = "CONQUEST";///服务的AE

///查询10天内的Study数据(前提是服务器那边支持)
DicomDateRange SearchDateRange= new DicomDateRange(DateTime.Now.AddDays(-10), DateTime.Now);
DicomClient client = new DicomClient(pacsIp, pacsPort, false, localAe, remoteAe);
//var cfind = DicomCFindRequest.CreateStudyQuery(null,null,SearchDateRange);//调用演示例子
//由于本次测试的服务端并不支持时间范围查询 所以我这里测试没用加这个条件
var cfind = DicomCFindRequest.CreateStudyQuery();
///C-Find绑定结果回调事件 接收服务器返回的结果
cfind.OnResponseReceived = (rq, res) =>
{
          Console.WriteLine("cfind 请求完成");
          string StudyInstuceUID = res.Dataset?.GetSingleValueOrDefault<string>(DicomTag.StudyInstanceUID, "");

         if (res.Status==Dicom.Network.DicomStatus.Success)
          {
                        Console.WriteLine("C-Find查询结束");
                        return;
		 }
          //到这里就可以拿到返回StudyInstuceUID 为后续的C-Move 做准备
          Console.WriteLine($"CFind 返回StudyInstuceUID :{StudyInstuceUID} ");
 };
///添加请求
client.AddRequestAsync(cfind).Wait();
///发送请求
client.SendAsync().Wait();
  1. C-Move 释义:就是发送一个指定StudyInstuceUID查询的然后 服务器会将查询结果以CStore的方式发送到指定的SCP收图服务 例子:
DicomClient CMoveClient = new DicomClient(pacsIp, pacsPort, false, localAe, remoteAe);

///理解这里耗费了学习过程的大部分时间
string TargetAe="CStoreSCP";//注意 这个是服务端配置的 请求成功后 服务会往对应的节点发送CStore文件请求
///创建CMove请求 指定对应的TargetAe 以及需要目标 StudyInstuceUID
DicomCMoveRequest CMoveRequest = new DicomCMoveRequest(TargetAe, StudyInstuceUID, Dicom.Network.DicomPriority.Medium);
///CMove绑定结果回调事件 接收服务器返回的结果
CMoveRequest.OnResponseReceived +=
(Dicom.Network.DicomCMoveRequest rq1, Dicom.Network.DicomCMoveResponse rs) =>
 {
        //成功后pacs会往指定的AE(TargetAe)发送CStore文件请求
	    if (rs.Status == Dicom.Network.DicomStatus.Success)
      {
             Console.WriteLine("CMove 请求完成");
             return;
      }
};
///添加请求
CMoveClient.AddRequestAsync(CMoveRequest).Wait();
///发送请求
CMoveClient.SendAsync().Wait();

说明:由于Fo-DICOM 的开源库 使用 版本不一样,可能会出现代码不完全一样的情况。

本文测试使用的模拟服务器软件是 CONQUEST 有兴趣的可以去官网下载一个做模拟测试

补充展位 Pages_Weblog_Get#0
补充展位 Pages_Weblog_Get#1