1.背景:
前段时间,项目经理到我工位上找我帮忙看一个问题。我们公司在某家县级医院上线的头颈/冠脉服务器,生成的胶片无法推送给医院的唯一的一台富士DRYPIX4000打印机,无法完成自动打印的功能。
虽然其他主要核心功能都已经验收通过,但由于无法自动完成打印胶片的功能。因此设备科主任一直不肯签字,导致验收无法完成,公司拿不到款项。
我当时了解了这件事情后,虽然我并没有接触过胶片打印的相关实现逻辑,但感觉还是比较蹊跷。因为在其他的医院并没有报过类似的问题。而且,胶片其实也是dicom图像,它的传输和打印的流程,都有DICOM标准规定好的步骤。
2.问题排查:
由于该打印机,还连接了医院的其他PACS工作站。而且这些工作站,可以顺利地把图像推送到打印机进行打印。因此,首先排除是打印机本身的问题。
对于医学影像的网络传输问题,首先需要确认两台设备之间的连通性,也就是DICOM协议中的C-ECHO。
在DICOM 3.0标准的第四章,关于Service Class Specifications(服务类的介绍)中,C-ECHO被定义为: Verification Service Class (Normative)
python
The Verification Service Class defines a service that verifies application level communication between peer DICOM AEs.
This verification is accomplished on an established Association using the C-ECHO DIMSE-C service.
C-ECHO, 相对于我们平时在定位网络问题时,就是: ping, telnet等命令。
因此,我在服务器,根据我们服务器的ip, 以及医院的CT机,打印机,PACS工作站,都进行了echoscu的连接测试。
经过连接测试后,我们的服务器,除了能和医院的CT机器和PACS能正常的建立连接外,跟医院的影像工作站,打印机均无法通过echoscu的连接。很多的报错,都是提示: "never connected."

因为在我的眼里,我认为的连接方式,是如下图所示的:

就是我们的服务器,和其他的设备,都是直接用一根网线连在一起的,中间不应该有什么阻拦。但是,为什么就有的能连通,有的就死活连不通呢。这解释不通呀!
后来想想,这不就是古人认识世界的方式吗。认为地球是整个宇宙的中心,太阳,月亮,以及其他的星星,都是围绕着地球在转的,也就是"地心说"。
后来当问题查明后,我才知道自己到底有多无知了!
而且由于需要打印机的人员也到场,才能协助定位问题。打印机的人员,给出了在他们的机器上看到的日志。由于他们也是出差到现场协助解决。由于我们未定位到具体的原因,打印机的运维人员,也不可能一直等着我们。他们走了以后,就更没有人来协助我们定位问题了。

打印机的工作人员说,是不是我们给他们传的胶片图像有问题哦。而其实,我们压根就还没到传送胶片图像的阶段呢,仅仅是在建立TCP连接的过程中,就被拒绝连接了。
由于现场,PACS是可以将图像传输到打印机上的。我们甚至和信息科咨询说,能否把我们AI服务生成的头颈/冠脉的胶片图像,先推送到PACS上,再从PACS上,把我们的胶片,推送到打印机上进行打印。
我们的提议,也遭到了医院信息科主任的强烈反对,并质疑我们不懂医院的业务。怎么能随便就把胶片的图像,传到PACS上呢。
那段时间,我甚至在网上下载了富士打印机的《用户手册》,希望从他们的用户手册中,看能不能找到一些解决问题的线索。
我甚至看到他们的手册中说,有可能早期的打印机,还不支持C-ECHO这样的dicom协议。
但是,这仍然无法解释,为什么我们的头颈/冠脉服务器,也连不上除PACS外的其余影像工作站。
这个问题,断断续续困扰了我一个多星期,我却仍然没有找到好的解决方案,连思路都没有。
而为了推送验收,我们又约了打印机工程师,约定好一起去这家医院,解决问题。公司也派了技术很牛的线上支持组的同事到现场协助。
3. 现场定位问题:
当同事到达现场后,她了解了基本的情况后,便开始做各种各样的连接测试。比如把我们的头颈/冠脉服务器,直接搬到信息科,先看能不能和信息科的网络互通,确认我们的服务器,和医院信息科的网络是互通的。
后来,她使用了tcpdump, 然后"截获"了从我们服务器到打印机的网络信息,导出成一个.pcap的抓包文件。然后再把这个抓包文件,导入到wireshark里面,查看。
顿时,情况便明了了。
原来echoscu, 只能看到了连接被拒绝,而在wireshark里面,却看到了整个网络请求的脉络。清晰地看到了,原来我们的请求,是被医院的一个Ruijiexxxx的交换器给拦截了。

而最关键的消息,是序号为第14~16条的消息。
第14个包,是我方服务器(150.102.101.80),向ip为(150.102.101.80), AE_TITLE=DRYPIX4000的打印机发送了一个echoscu的请求。我方的AE_TITLE是ECHOSCU.
第15个包,是我方服务器,接到了对方返回的一个类型为 RST的包。而RST, 是重置连接的意思。也就是说,我们请求打印机的连接,被拒绝和重置了。
第16个包,我方服务器在接到了对方的RST的返回后,也给予了确认,[RST, ACK],断开连接;
最终双方完成了本次对话。
通过抓到的包,可以了解到,在我们服务器和打印机之间,还是存在着其他的网络节点的,就是Ruijiexxx的节点。后来我们的同事,去找信息科的老师,信息科老师根据我们排查到的问题后,找到对应的网络节点的配置,修改了一些规则后,再次测试,我们的冠脉/头颈服务器,终于可以和打印机建立连接,可以正常的打印了。
而据同事的实地调研,她绘制了一张该医院的网络拓扑图。当她出差回来后,我问她现场的实际情况时,她给我展示了那张图,令我印象深刻。

曾经,我以为的部署方式,是我们的头颈/冠脉的服务器,和医院的打印机,是直接连通的。而实际上呢,我们的服务器,在五楼,打印机在一楼。我们的服务器,和打印机,中间有三个交换机。只有这三个交换机都放行,我们才能和打印机完成通讯,和打印的事务。
<这就像一个一直秉持地心说的顽固老朽,突然看到了宇宙和太阳系的真相的时刻。地球只是围绕太阳旋转的一颗星球。而宇宙中,还有无数像太阳系这样的星系。>
任何一台交换机的拦截,都会使连接无法成功。而这些问题,医院的信息科老师不会告诉你,我在terminal里面,敲一万次echoscu, 也发现不了问题的关键。而仅仅是通过掌握tcpdump和wireshark两个工具的使用,和几条简单的抓包指令,就能解决一个在我看来无解的问题。
4.事后总结:
经过这一次现场问题的跟进和解决,我了解到,自己的技术功底和技能树,还是太薄弱和单调了。我虽然看似对医学影像处理比较了解,但是在解决一些涉及到网络传输方面的问题时,却是一个彻彻底底的小白。甚至,都不知道该用什么工具去解决。
技多不压身,工欲善其事,必先利其器。要想在技术这条路上走下去,必须不断地学习,补上自己的知识短板,通过一次一次问题的解决,让自己成为一个技能点更加完善的工程师,能够成为为前场同事兜底的中流砥柱。
放弃自己的傲慢和无知,认真思考,勤于动手,不负韶华!
接下来,我会再专门写一篇,用wireshark抓包,来展示DICOM常用的网络协议的通讯过程的文章,敬请期待!