☰
ConquestDICOMServer:本地 DICOM SCP 测试环境搭建与避坑
2026/9/26 6:48:58 网站建设 项目流程

简介:Conquest DICOM Server 是一款开源的 DICOM 服务器测试工具,面向医疗影像软件开发者、PACS 管理员及系统集成测试人员,可作为 DICOM SCP 接收和存储影像、响应工作列表查询,用于模拟真实设备、验证网络通信与排查集成问题。资源包约 22.28MB,内含服务器主程序 ConquestDICOMServer.exe、控制台脚本 console.bat、自动更新与 Web 安装脚本、CqDicom.dll 核心库、dgate.dic 字典、数据匿名化脚本以及 7za.exe 等工具,覆盖服务启动、配置维护、数据处理与归档场景。目前已有 716 人学习,借助这套工具可以低成本搭建测试环境,掌握 DICOM 图像收发、工作列表调试、匿名化处理和跨 PACS 数据迁移的实践方法;从安装脚本到匿名化配置一应俱全,便于按需调用,也可通过日志观察评估服务器负载,为医疗系统上线前的兼容性与性能验证提供参考。

1. 为什么我建议拿 ConquestDICOMServer 当 DICOM 测试工具用

做过 PACS 对接或者影像设备联调的人,一定对测试 DICOM 传输这件事不陌生。手里没有一套稳定可控的 DICOM SCP 服务端,联调就是一场灾难:设备厂商的测试环境说关就关,医院 PACS 那边的 SCP 端口你也不能随便乱发假数据去撞,出了问题连是谁的锅都说不清楚。ConquestDICOMServer 在 DICOM 测试工具这个圈子里,算是一个绕不开的名字,它本身是一套开源的 DICOM SCP 服务,支持存储、查询、Retrieve,同时也自带 Worklist 服务能力。对做医学影像集成、PACS 测试、设备调试的人来说,它就是那个能让你随时在本地搭一个 DICOM 节点、随便收发数据、测完就删的沙盒。

这个工具解决的核心问题是:你不需要依赖厂商环境,也不用在真实的 PACS 上做破坏性测试,自己花十几分钟就能起一个像模像样的 DICOM SCP,并且支持完整的 Storage 和 Worklist 流程。适合三类人:一类是医院信息科的工程师,需要在接入新设备前验证 C-FIND/C-STORE 流程;一类是厂商实施人员,需要复现客户环境里的传输异常;还有一类是做 PACS 研发、写 DICOM 解析代码的开发者,需要一个行为可控的服务端来配合打点调试。我最早接触 Conquest 是在一批超声设备的数据迁移项目里,当时用它把不同厂商设备的 DICOM 文件做了大量吞吐测试,发现这个轻量级 SCP 的稳定性和日志完整度都比想象中好,才真正把它当成一个正经测试工具来用。需要提醒的是,它毕竟不是一个商业级 PACS,不适合拿去做海量高并发压力测试,但在联调验证这个尺度上,它非常能打。

2. 从下载到跑起来:ConquestDICOMServer 的最小可用配置

2.1 装之前必须先想清楚:你要拿它当 SCP 用还是当 Worklist 服务用

ConquestDICOMServer 这个工具支持多进程架构,一旦跑起来,它可以同时承担 DICOM SCP 存储服务、Worklist SCP,以及 Web Server 三个角色。很多人第一次接触它,容易把它当成一个单纯的 DICOM 文件收发工具来看,这会在后面的配置上走不少弯路。如果你只是做 Storage 测试,核心是配置好 SCP 的端口和 AE Title;如果你要测 Worklist,那就需要额外配置数据库和 HL7 接口。

先搞清楚一个基本概念:DICOM 是医学数字影像通信标准,SCP 是服务类提供方(Service Class Provider),也就是接收请求的一方。你日常用 Conquest 时,大部分工作发生在它作为一个 SCP 角色接收来自设备或测试工具的 C-STORE 请求时。所以,你测试工具里填的目标 AE Title 和目标端口,必须和 Conquest 的 dgatesop 配置完全对上,否则你发出去的 C-STORE 请求直接就被拒了。

2.2 下载与目录文件:别看文件多,关键就那三个

首先去官方源下载 Windows 版(如果你是 Linux 环境,有对应的源码包可以自己编译,但日常测试用 Windows 可执行包最省事)。解压后,你不需要关心所有文件,只需要记住三个核心东西:

  • dgate.exe:这是 Conquest 的主服务进程,所有 DICOM 服务都靠它跑,测试时你要先保证这个进程存活。
  • dgatesop.lst:这个文件里存的是 SCP 配置,等会真正要动的就是它,里面定义了端口、AE Title、存储目录。
  • dicom.ini:主配置文件,数据库类型、日志路径、网络绑定地址都在这里写。
# 注意:以下命令在 Windows 的 DOS 窗口里执行 cd D:\Conquest-DICOM-Server # 第一次启动时,先手动跑一下主进程,看有没有缺库报错 dgate.exe

我第一次解压后就直接双击 dgate.exe,结果报了一个数据库连接错误,原因是没有初始化数据库。Conquest 用的是 SQLite 作为默认数据库,但第一次使用你需要允许它自动创建数据库文件。

注意:第一次启动最好是手动运行 dgate.exe 而不是做成 Windows 服务,因为手动运行你能直接看到初始化日志。如果初始化失败你做成服务,排错起来就非常被动。

2.3 修改 dicom.ini:端到端的最小配置模板

dicom.ini 是 Conquest 启动时第一个读取的文件,里面很多参数你暂时不用动,但有几个直接决定了你测试能不能通。以我经常用来做测试的一套配置为例:

[ssc] ServerType = SQLite LocalAET = CONQUESTSRV TCPPort = 5678 TCPPortWorklist = 5679 ProcessorThreads = 8 RootDirectory = D:\Conquest-DICOM-Server\Data

这里的LocalAET是这台测试服务器的 AE Title,TCPPort是主存储服务的端口,TCPPortWorklist是 Worklist 服务端口。在实际测试中,我习惯把 Worklist 端口和主端口分开,这样测 C-FIND 时不会和 C-STORE 请求互相干扰。你可能注意到了,我用的是 5678 而不是常见的 104,因为很多测试环境里 104 需要管理员权限,而 5678 这种高位端口不受限制。

修改完 ini 之后,保存退出,再把 dgate.exe 重新运行一遍。这次如果看到日志里出现类似Listening on port 5678的信息,那说明 Conquest 的 SCP 服务已经起来了。这个时候你的 DICOM 测试工具里,目标 AE Title 就要写成CONQUESTSRV,端口写5678。

2.4 建库与目录准备:不准备好这些,测试中段容易翻车

Conquest 的存储逻辑是:每个接入的 Calling AE Title 对应一个独立的子目录,文件按 Study 组织。如果你没有为测试创建的 AE Title 预先建好目录,它会自动在 RootDirectory 下创建。这个机制对临时测试很方便,但有个坑:如果你测试时频繁更换 AE Title,磁盘上会留下大量垃圾目录。所以我的习惯是,在测试之前先手动把目录结构建好:

mkdir D:\Conquest-DICOM-Server\Data\TESTSRC mkdir D:\Conquest-DICOM-Server\Data\TESTDST

这里TESTSRC模拟发送端设备,TESTDST是接收端。然后用文本编辑器打开 dgatesop.lst,添加对应的 SCP 定义。dgatesop.lst 里每一行的格式是:

# AE Title, 描述, 主机名/IP, 端口 TESTSRC, 模拟超声设备, ANY, 5678 TESTDST, 模拟PACS归档, ANY, 5678

逻辑就是:当测试工具用TESTSRC这个 AE Title 发数据过来,Conquest 就把数据存到对应目录。主机名写 ANY 表示不做 IP 过滤,这在局域网测试里很常用,但如果你面对的是公网环境,建议写成具体的 IP 地址,否则随便一台机器都能往里发数据。

3. 三种实操场景:从存储曲线到 C-FIND 查询再到 Worklist 验证

3.1 场景一:用 Conquest 做 C-STORE 接收的整条链路测试

这是最基本的测试场景。你的被测设备或者 DICOM 测试工具(比如 dcm4che 的 storescu)向 Conquest 发送 DICOM 文件,Conquest 作为 SCP 接收并落盘。跑通这条链路,证明你的设备端 C-STORE 的 AE Title、IP、端口设置没有错位。

在 Windows 上测试,我会用 dcm4che 工具包里的 storescu 命令,它跑在同一个局域网内,往 Conquest 上发文件:

# 用 dcm4che 的 storescu 向 Conquest 的 SCP 发送一副 CT 图像 storescu -c CONQUESTSRV@127.0.0.1:5678 -aec CONQUESTSRV D:\testdata\ct_slice.dcm

这行的核心参数是-c后面的CONQUESTSRV@127.0.0.1:5678,CONQUESTSRV 是目标 AE Title,127.0.0.1 是 Conquest 所在机器地址,5678 是端口。-aec指定请求的 Calling AE Title,如果 Conquest 在 dgatesop.lst 里对 Calling AE 做了限制,这里的值必须匹配。发送成功后,从 Conquest 日志里能看到类似C-STORE received的记录,同时到 Data 目录下去看,应该多了一个按 Study UID 命名的文件夹,里面就是接收到的 dcm 文件。

如果 C-STORE 发不出去,或者被拒绝,第一个要查的就是-aec这个参数。很多厂商设备里配置的 AE Title 是固定不能改的,如果你在 Conquest 那边限制了合法的 AE Title 列表,你的测试请求头里带着一个不在名单里的名字,直接被拒。逻辑上 Conquest 的 SCP 服务和设备端的 Store SCU 是握手关系,两边 AE Title 必须互相认识。

3.2 场景二:验证 C-FIND 查询:从服务端查回已有 Study 信息

存储测试通过之后,你需要验证查询能力,也就是 C-FIND。这时候 Conquest 不只是接收文件,还要能回应 Query 请求。查询测试的意义在于,你不仅能发数据过去,还能验证数据是否可被检索到。常用的测试工具是 dcm4che 的 findscu:

# 在 Query Retrieve Level=PATIENT, 查所有患者 findscu -c CONQUESTSRV@127.0.0.1:5678 -m QueryRetrieveLevel=PATIENT -m PatientName="*" -aec CONQUESTSRV

这里-m是匹配关键字。PatientName="*"表示通配所有患者。正常情况下,findscu 会把前一步存进去的那条记录的患者信息列出来。如果查不出来,常见原因是发送 C-STORE 时文件里的 PatientName 是空的,或者在存储时被 Conquest 过滤掉了。遇到查不出数据的情况,先在 Conquest 的查询工具界面里直接搜一下患者姓名,如果里面能看到数据但 findscu 查不出来,那就是查询匹配级别的问题,把-m QueryRetrieveLevel=PATIENT改成-m QueryRetrieveLevel=STUDY再试一次。

C-FIND 这块要记住,Conquest 的查询是精确匹配和通配符配合的。你从工具里发PatientName=""空字符串,它不会返回全部记录,要用*。这是很多新手第一次测 C-FIND 时最容易翻车的地方。

3.3 场景三:Worklist 测试,工作量清单的完整闭环

如果你的设备要做 Worklist 查询(比如 DR/超声设备开机后自动去影像服务器拉检查清单),Conquest 的TCPPortWorklist就派上用场了。Worklist 不是查“已存在的影像”,而是查询“今天安排了哪些检查”。设备端用 C-FIND 到 Worklist SCP,查询条件是 Accession Number、Patient ID 或者 Requested Procedure ID。

Conquest 的 Worklist 数据来源有两种:一种是把预约信息直接写进数据库,另一种是通过外接 HL7 接口接收,后者需要额外配置。对测试工具来说,最直接的验证手段是把一条 DICOM Modality Worklist 记录通过工具直接写进 Conquest 数据库,然后用设备端去拉取。Windows 下有一个自带的命令行辅助:

# 在 Conquest 安装目录找到 dgate.exe 同目录下的 dgate --lx 工具, 用于往数据库里写测试 Worklist dgate --lx "C:\testwl\worklist.xml"

这行命令的意思是让 Conquest 读取一个 XML 定义的患者预约信息,写入数据库的 Worklist 表。你需要先构造好 XML 文件,里面至少包含ScheduledStationAETitle、PatientID、PatientName、RequestedProcedureID这几个 Tag。写完以后,用测试工具向 Worklist 端口 5679 发起 C-FIND,能查到这条记录,Worklist 验证就闭环了。但这是最容易出问题的一环,因为你查不到记录时,几乎无法确定是设备端查询参数不对,还是数据写入格式不对。我的建议是先查设备端发出来的 C-FIND 请求内容,把里面的 Query 条件抄出来,再对照 XML 里的值,看看是不是 ScheduledStationAETitle 带空格之类的细节差异。

4. 避坑与常见问题排查:我踩过的 Conquest 测试工具坑

4.1 报错 Connection Refused,但 Conquest 明明启动了

现象:你从测试工具里发 C-STORE 请求,报 Connection Refused,端口不可达;但检查 Conquest 进程,它确实在运行。

原因:90% 的情况是你改完 dicom.ini 之后没有重启进程。Conquest 这个工具和大部分服务不太一样,它修改端口和 AE Title 后不会自动热加载,必须重启 dgate.exe。剩下的 10% 是端口绑定地址问题,如果你在 dicom.ini 里写死了绑定 IP,而测试工具访问的是另一个 IP,就会拒绝。解决:先关掉 dgate.exe 进程,再重新启动,然后去日志确认是否显示端口监听地址。我一般在启动后用 netstat 再看一眼端口占用:

netstat -an | findstr 5678

如果看到 LISTENING 状态,说明端口确实在监听,这时候再回头检查测试工具里的目标地址到底是不是 127.0.0.1。

4.2 文件能发成功,但 Data 目录里找不到接收的文件

现象:测试工具提示 C-STORE 已经成功,但你去 RootDirectory 指定的目录下翻,没有看到新的子目录和 DICOM 文件。

原因:Conquest 存储文件时不直接按 RootDirectory 存放,而是按 Calling AE Title 再套一层目录。如果你的测试工具 -aec 值写的是CONQUESTSRV,而 dgatesop.lst 里定义的接收 AE 是TESTDST,数据会被存到名为 CONQUESTSRV 的目录下,而不是你以为的 TESTDST。解决很简单,去 RootDirectory 下找找有没有跟测试工具 AE Title 同名的文件夹。你不能用“我认为应该在哪”来推测,日志里每一条 C-STORE received 后面都会带着存储路径,直接看日志最省事。

4.3 SCP 能收到文件,但 C-FIND 一查就返回空,明明数据已经存在了

现象:你通过 storescu 成功发了一张图进去,用 findscu 查询,结果一条匹配都没有。

原因:这里要看查询级别和匹配值。Conquest 的数据库索引是基于 Patient ID、Patient Name、Study Date 这些标准 Tag 的,如果你发送的 DICOM 文件里这些 Tag 本身就是空的,索引建不起来,后面无论你怎么查都是空结果。这就是典型的“脏数据进,查不出来”的翻车场景。解决:回到源头看那个 dcm 文件是不是自带完整 Patient 信息。用一个命令先确认你要发的文件里面有哪些属性:

dcmdump -P D:\testdata\ct_slice.dcm | findstr Patient

如果发现 PatientName 是空,直接从别的数据源重新导出再测。临时的办法是改文件后重新发送,但我不建议在测试里用这种歪路子,因为查出来的数据和真实场景不一致,很容易给你一个假阳性结论。

4.4 Worklist 测试时设备能连上,但迟迟不返回预约清单

现象:设备端显示 Worklist 连接成功,但查询后返回无记录;或者设备直接卡住,直到超时。

原因:第一,没有往 Conquest 的 Worklist 表里预填任何数据。Worklist 不像 C-STORE 自动收数据,它需要你先写数据进去,查询才有返回。第二,Worklist 端口和存储端口搞混了,设备查 Worklist 应该连 5679,连成 5678 端口之后,Conquest 拿到的 Mismatch,返回空列表是很正常的事情。解决:再次核对设备设置里的端口,确认指向TCPPortWorklist指定的值。另外用 Worklist 日志来看,Conquest 的日志里会记录 C-FIND 请求的整个 DICOM 消息,你从中能看到设备端查询时用的ScheduledStationAETitle到底是什么值,再回填到 XML 数据里保证两者一致。

4.5 测试中途 dgate.exe 突然退出,数据库日志报 disk I/O error

现象:存储测试跑了一段时间,dgate.exe 进程自动消失,重启后提示数据库文件已损坏。

原因:这个我遇到过几次,大部分是机器的杀毒软件在后台扫描RootDirectory,和 Conquest 的 SQLite 数据库写入起了冲突。Conquest 默认把数据库和接收的 DICOM 文件放在同一个目录,杀毒软件频繁访问这个目录,而 SQLite 写入时文件锁被干扰,就会造成异常退出。解决:把RootDirectory改成杀毒软件排除目录,或者干脆把测试环境放到不装杀毒软件的内部虚拟机里跑。这个操作对于长期压力测试尤其重要,别等跑出几十个 G 的数据后才发现进程早就没了。

5. 把 Conquest 从手工测试工具变成自动化测试基座

5.1 用命令行参数实现半自动化存储收发验证

前面的操作都是手工一条条发命令,但实际上 Conquest 停掉再用 dgate.exe 重新启动时,本身支持命令行参数,这为自动化脚本留了空间。如果你在 CI 环境里做每日集成测试,可以这样写一个批处理脚本:

@echo off REM 重启 Conquest 并等待端口就绪 taskkill /IM dgate.exe /F timeout /t 3 /nobreak >nul start /B D:\Conquest-DICOM-Server\dgate.exe echo "等待 Conquest 启动..." for /L %%i in (1,1,30) do ( netstat -an | findstr 5678 >nul if not errorlevel 1 ( echo "Conquest 已就绪" goto READY ) timeout /t 1 /nobreak >nul ) :READY echo "开始发送测试数据..." storescu -c CONQUESTSRV@127.0.0.1:5678 -aec CONQUESTSRV D:\testdata\batch01\*.dcm

从这个脚本里你可以看到两个关键点:一是启动了延迟探查机制,等端口真正在监听再去发数据,避免测试工具连空窗期;二是批量发送所有 dcm 文件而不是一个个手工输。对于一天要重复跑几十遍回归的人来说,这个自动化能省下大量等待时间。

5.2 利用日志文件辅助自动断言

Conquest 的日志系统在测试自动化中价值非常高。每一条 C-STORE、C-FIND 记录都写在了 dgate.log 文件里。我之前写过一个简单的自动化校验逻辑:发送完成后,去 dgate.log 里统计新一轮日志中的C-STORE received行数,如果数量和发送的文件数量一致,则判定测试通过。这个验证思路绕开了“文件是否真落盘”这个可能被缓存欺骗的检查,直接看服务端的业务日志,更可靠。

5.3 清理测试数据的方法

测试做多了,Conquest 的数据库会积累大量垃圾数据。如果不清理,查询测试会越来越慢,还会影响后续测试结果的判定,因为旧数据的干扰会让 C-FIND 返回结果里混进来一堆无关记录。我一般用两种方式清理。简单方式是直接在 Conquest 的 Web 界面里选中所有记录删除,适用于数据量少的情况。数据量大时,我直接把整个数据库文件删掉,让它重新初始化,再把 Data 目录里的子目录一并清空。需要注意的是,删除数据库之前一定要先关掉 dgate.exe,否则你删了文件,进程打开句柄还在,Windows 会报文件占用。从那以后,我每次自动化测试跑完,都强制走一遍进程检查、数据清理和端口状态确认这三步,再开始下一轮测试。这样做下来,Conquest 这个测试工具基本没有再因为环境残留的问题给我出过假结果。说到底,DICOM 联调这件事,比的不是谁的工具多,而是谁能在最短时间内复现问题、定位问题。希望这些用法能帮你在下次医院项目联调时少熬几个夜。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询