背景:
上一篇博文对DICOM中的网络传输进行了介绍,主要参照DCMTK Wiki中的英文原文。通过对比DCMTK与fo-dicom两个开源库对DICOM标准的具体实现,对理解DICOM标准有一个更直观的认识。此篇博文是对上一篇博文的补充,因为专栏前面的示例大多是利用DCMTK工具包来进行的,此次借着分析fo-dicom源码结构的机会,参照fo-dicom的README.md,给出C-ECHO 和C-STORE服务的具体实现。在实现的同时给出DICOM3.0标准中的相关介绍,帮助我们理解。
C-ECHO的fo-dicom实现:
1)C-ECHO参数说明:
C-ECHO又叫验证服务(即Verification),是用来验证DICOM服务两端的交流是否畅通。DICOM3.0的第7部分给出了C-ECHO服务的参数,如下图1所示:
【注意】:这里讲解一下DICOM3.0标准的阅读方法。以DICOM3.0标准的第7、8部分为例,【第7部分】中第9章开始讲解DIMSE-C的各种服务,依次为C-STORE、C-FIND、C-GET、C-MOVE、C-ECHO(上图1就是我在该部分的C-ECHO小节中截取的),其中前半部分主要给出了DIMSE-C各种服务的参数,这里仅仅是罗列出DICOM3.0标准的要求,目的是让你明白各个服务参数是否是必要的(分别用M、U、=表示);后半部分开始讲解DIMSE-C各种服务的协议及实现流程(即Protocol和Procedures),在PROTOCOL中给出的是具体的DIMSE-C服务的各种指令在传输过程中的格式,该部分也就是你利用抓包工具能够直接抓取的真实数据流;在Procedures中给出的是SCU和SCP之间的交互流程,通常为了说明服务是由谁发起的,由谁响应。在介绍Protocol的时候对于比较复杂的、可变的区域(Variables Fields)通常会放在附录中,例如第7部分的附录C和E等;【第8部分】与【第7部分】类似,从第7章开始介绍ACSE的各种服务的参数(如下图2所示),依次为A-ASSOCIATE、A-RELEASE、A-ABORT、A-P-ABORT、P-DATA;第9章给出的是ACSE中各种服务的结构,即STRUCTURE,该部分与【第7部分】中的PROTOCOL相同,给出的是具体ACSE PDU在传输时刻的数据格式,该部分也是可以通过抓包工具直接获得的;同样对于比较复杂的STRUCTURE介绍也会单独放到附录中,例如第8部分的附录E。
fo-dicom对于DIMSE消息的实现基类是DicomMessage,针对请求和响应分别派生出了DicomRequest和DicomResponse,最后根据不同的DIMSE服务派生相应的类。C-ECHO是其中最简单的,fo-dicom已经给出了SCP和SCU的具体实现。参照fo-dicom中的README.md文件,给出C-ECHO SCP和SCU的代码,详情如下:
2)C-ECHO代码实例:
C-ECHO SCP的代码是直接利用了fo-dicom给出的DicomCEchoProvider类,通过创建DicomServer(12345)对象,开启C-ECHO SCP服务,其中参数12345表示C-ECHO服务的端口号。C-ECHO SCU和C-ECHO SCP的代码分别如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Dicom;
using Dicom.Network;
namespace CEchoSCU
{
class Program
{
static void Main(string[] args)
{
var client = new DicomClient();
client.NegotiateAsyncOps();
client.AddRequest(new DicomCEchoRequest());
client.Send("127.0.0.1", 12345, false, "SCU", "ANY-SCP");
Console.ReadLine();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using Dicom;
using Dicom.Network;
namespace CEchoSCP
{
class Program
{
static void Main(string[] args)
{
var server = new DicomServer(12345);
Console.ReadLine();
}
}
}
实际运行结果如下:
C-STORE的fo-dicom实现:
1)C-STORE参数说明:
C-STORE就是存储服务,在医疗信息系统中最常见的服务之一,尤其是PACS系统中。与C-ECHO服务相同,DICOM3.0标准第7部分也给出了C-STORE服务的参数列表,如下图4所示:
该参数列表的目的同