在使用Dcmtk工具模拟PACS通信时,发现C-MOVE操作在Win10本地环境下服务端和客户端相互通信时可以成功,但在Ubuntu作服务端,Win10作客户端的情况下总是失败。一开始我以为是Win10防火墙设置的问题,但后来发现问题并不在这里。本文记录了解决这个问题的过程。
Dcmtk Wiki DcmSCU example program
Dcmtk Forum C-MOVE Response (Refused: OutOfResourcesSubOperations)
Dcmtk Forum Receiving Images from PACS using DCMSCU
vmware虚拟机三种网络模式详解
e:
cd E:\DCMTK\PACS\SCP
dcmqrscp -d --config dcmqrscp.cfg
e:
cd E:\DCMTK\PACS\SCU
echoscu -d localhost 11112 -aec ACME_STORE -aet ACME1
movescu -d -S -aec ACME_STORE -aet ACME1 -aem ACME1 --port 1234 -od E:\DCMTK\PACS\SCU\database localhost 11112 -k QueryRetrieveLevel=STUDY -k StudyDate=20140101
NetworkTCPPort = 11112
MaxPDUSize = 16384
MaxAssociations = 16
HostTable BEGIN
acme1 = (ACME1, DESKTOP-ASCCO8S, 1234)
acme2 = (ACME2, Ubuntu-Qin, 5678)
acmeCTcompany = acme1, acme2
HostTable END
VendorTable BEGIN
"Acme CT Company" = acmeCTcompany
VendorTable END
AETable BEGIN
ACME_STORE E:\DCMTK\PACS\SCP\database RW (100, 1024mb) acmeCTcompany
AETable END
su root
cd /etc/dcmtk
cp dcmqrscp.cfg dcmqrscp.bak
vim dcmqrscp.cfg
dcmqrscp -d -c dcmqrscp.cfg
dcmqrscp.cfg 内容如下
NetworkTCPPort = 11112
MaxPDUSize = 16384
MaxAssociations = 16
HostTable BEGIN
acme1 = (ACME1, 192.168.141.1, 1234)
acme2 = (ACME2, localhost, 5678)
# acme3 = (ACME3, 192.168.6.212, 1235)
acmeCTcompany = acme1, acme2,acme3
HostTable END
VendorTable BEGIN
"Acme CT Company" = acmeCTcompany
VendorTable END
AETable BEGIN
ACME_STORE /var/lib/dcmtk/db/ACME_STORE RW (100, 1024mb) acmeCTcompany
AETable END
ping Ubuntu-Qin
e:
cd E:\DCMTK\PACS\SCU
echoscu -d Ubuntu-Qin 11112 -aec ACME_STORE -aet ACME1
storescu -d Ubuntu-Qin 11112 ct.dcm -aec ACME_STORE -aet ACME1
findscu -v -S -aec ACME_STORE -aet ACME1 Ubuntu-Qin 11112 -k QueryRetrieveLevel=STUDY -k StudyDate -k StudyDescription -k StudyInstanceUID
movescu Ubuntu-Qin 11112 -v -S -aec ACME_STORE -aet ACME1 -aem ACME1 --port 1234 -od E:\DCMTK\PACS\SCU\database -k QueryRetrieveLevel=STUDY -k StudyInstanceUID=2.16.840.1.113662.2.1.1519.11582.1990505.1105152
发现Ping,Echo,Store,Find操作都能成功,唯独Move操作失败。Server能接收到Client发来的Move请求,在输出Requesting Sub-Association之后卡好久,最终显示错误信息为Refused:OutOfResourcesSubOperations。
前面的 参考资料2 中有以下描述:
An error during MOVE that refers to sub operations always refers to a problem on the second connection, i.e. the connection the PACS is starting to the storage server in order to send the images. Probably the storage server is behind a firewall, not configured correctly in the PACS (e.g. wrong port or IP address), which is in your case the dcmqrscp config file.
可以看出OutOfResourcesSubOperations 发生在PACS想要发送数据(在这里是CT图像)给Client时。可是即使设置防火墙开放端口1234(百度经验:Win10系统如何在防火墙里开放端口)之后(这一步实际上不需要),问题依然存在。难道是dcmqrscp.cfg 配置出现了问题?可是我们明明可以以ACME1作为AET和PACS通信啊?
部分原因是这样!
回想我们在Ubuntu系统dcmqrscp.cfg 中的配置,是将192.168.141.1 作为ACME1的IP地址。为什么呢?因为如果将主机Win10的真实IP地址 192.168.6.212 写入dcmqrscp.cfg ,使用echoscu命令会在客户端和服务端分别看到这样的日志
来自 192.168.6.212 (主机Win10的真实IP)的请求被识别为来自192.168.141.1(虚拟机Ubuntu VMNet8 的IP地址)!
因此我们将VMNet8 的IP地址写入PACS的配置中,就可以正常通信,我在错误示范中也正是这么做的。至于为什么请参见 参考资料4 vmware虚拟机三种网络模式详解
但是虚拟机Ubuntu向主机Win10发送请求(建立TCP连接)时并不是通过VMNet8的IP地址,而是使用真实IP 192.168.6.212 。。。
综上所述,我们在PACS服务端的dcmqrscp.cfg 配置并不完整,需要添加acme3 以让PACS与主机建立连接
NetworkTCPPort = 11112
MaxPDUSize = 16384
MaxAssociations = 16
HostTable BEGIN
acme1 = (ACME1, 192.168.141.1, 1234)
acme2 = (ACME2, localhost, 5678)
acme3 = (ACME3, 192.168.6.212, 1235)
acmeCTcompany = acme1, acme2,acme3
HostTable END
VendorTable BEGIN
"Acme CT Company" = acmeCTcompany
VendorTable END
AETable BEGIN
ACME_STORE /var/lib/dcmtk/db/ACME_STORE RW (100, 1024mb) acmeCTcompany
AETable END
但是这样做还不够,原因参见 参考资料4 。
我们还需要一个以acme3作为AET的storescp接收PACS发送的数据。
在Win10新建一个命令行窗口,输入
e:
cd E:\DCMTK\PACS\SCU\moveDest
storescp 1235 -d -aet ACME3 -od E:\DCMTK\PACS\SCU\moveDest
在Win10原来的命令行输入(这一步改变了 -aem 参数,其它不变)
movescu Ubuntu-Qin 11112 -d -S -aec ACME_STORE -aet ACME1 -aem ACME3 --port 1234 -od E:\DCMTK\PACS\SCU\database -k QueryRetrieveLevel=STUDY -k StudyDate=20140101
C-MOVE操作成功完成,Win10 E:\DCMTK\PACS\SCU\moveDest目录下新增文件 CT.2.16.840.1.113662.2.1.4519.41582.4105152.419990505.410523251。
大功告成!
我们终于实现了Win10作Client,Ubuntu作Server情况下的C-MOVE。但是还有一个问题,为什么Win10环境中不需要另开一个命令行窗口输入storescp接收数据呢?回忆一下这个命令
movescu localhost 11112 -d -S -aec ACME_STORE -aet ACME1 -aem ACME1 --port 1234 -od E:\DCMTK\PACS\SCU\database -k QueryRetrieveLevel=STUDY -k StudyDate=20140101
这里我们使用的主机名是localhost,aet和aem都设为ACME1,在Server和Client都处在Win10的环境下,两者都可以通过localhost进行连接,并且这里的端口号恰恰是1234,因此可以既发送请求又接收文件。为验证这一猜想,我们在Server和Client都处在Ubuntu环境的情况下验证这一想法。
mkdir scu
cd /etc/dcmtk/scu
movescu localhost 11112 -d -S -aec ACME_STORE -aet ACME2 -aem ACME2 --port 5678 -od /etc/dcmtk/scu -k QueryRetrieveLevel=STUDY -k StudyDate=20140101
/etc/dcmtk/scu 新增dcm文件,结果证实了我们的猜想:dcmqrscp.cfg 的配置不正确和虚拟机的网络通讯方式有很大关系。