关于使用Dcm4che实现CFindSCP以及CMoveSCP的问题

ba1yu 2024-07-29 15:23:32

目前我用dcm4che实现了CStoreSCP 并且可以接收图像了,目前现在我要实现CFindSCP以及CMoveSCP,在网上找了一点资料后,项目可以运行

代码如下

package com.annet.service;

import org.dcm4che3.data.Attributes;
import org.dcm4che3.data.Tag;
import org.dcm4che3.data.VR;
import org.dcm4che3.net.*;
import org.dcm4che3.net.pdu.PresentationContext;
import org.dcm4che3.net.service.BasicCFindSCP;
import org.dcm4che3.net.service.BasicCMoveSCP;
import org.dcm4che3.net.service.DicomServiceRegistry;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Dcm2cheService {

    private final Device device = new Device("1");
    private final ApplicationEntity ae = new ApplicationEntity("AIRKING");
    private final Connection conn = new Connection();

    ExecutorService executorService = Executors.newFixedThreadPool(10);


    private final BasicCFindSCP cfindSCP = new BasicCFindSCP("*") {
        @Override
        public void onDimseRQ(Association as, PresentationContext pc, Dimse dimse, Attributes cmd, Attributes keys) throws IOException {
            // Implement your C-Find logic here
            Attributes rsp = Commands.mkCFindRSP(cmd, 0); // Success
            Attributes match = new Attributes();
            match.setString(Tag.PatientName, VR.PN, "John Doe");
            match.setString(Tag.PatientID, VR.LO, "123456");
            as.tryWriteDimseRSP(pc, rsp, match);
            as.tryWriteDimseRSP(pc, Commands.mkCFindRSP(cmd, 0x0000)); // Final Response
        }
    };

    private final BasicCMoveSCP cmoveSCP = new BasicCMoveSCP("*") {
        @Override
        public void onDimseRQ(Association as, PresentationContext pc, Dimse dimse, Attributes cmd, Attributes keys) throws IOException {
            // Implement your C-Move logic here
            Attributes rsp = Commands.mkCMoveRSP(cmd, 0); // Success
            as.tryWriteDimseRSP(pc, rsp);
        }
    };

    public Dcm2cheService() {
        device.setDimseRQHandler(createServiceRegistry());
        device.addConnection(conn);
        device.addApplicationEntity(ae);
        ae.setAssociationAcceptor(true);
        ae.addConnection(conn);
    }

    public void setPort(int nPort) {
        if (conn == null) {
            return;
        }
        conn.setPort(nPort);
    }

    public void setIP(String strIP) {
        if (conn == null) {
            return;
        }
        conn.setHostname(strIP);
    }

    public void setAETitle(String strAETitle) throws IOException {
        ae.setAETitle(strAETitle);
        ae.addTransferCapability(new TransferCapability(null, "*", TransferCapability.Role.SCP, "*"));
    }

    public void startService() throws IOException, GeneralSecurityException {
        device.setExecutor(executorService);
        device.bindConnections();
    }

    private DicomServiceRegistry createServiceRegistry() {
        DicomServiceRegistry serviceRegistry = new DicomServiceRegistry();
        serviceRegistry.addDicomService(cfindSCP);
        serviceRegistry.addDicomService(cmoveSCP);
        return serviceRegistry;
    }
    public static void main(String[] args) {
        Dcm2cheService service = new Dcm2cheService();
        try {
            service.setIP("127.0.0.1");
            service.setPort(11118);
            service.setAETitle("AIRKING");
            service.startService();
            System.out.println(1);
        } catch (IOException | GeneralSecurityException e) {
            e.printStackTrace();
        }
    }
}




以下是执行main方法启动的控制台打印

 现在使用MicroDicom发送请求

 控制台报了一个空指针异常的错误

15:22:51.796 [pool-1-thread-1] INFO org.dcm4che3.net.Connection - Accept connection Socket[addr=/127.0.0.1,port=53116,localport=11118]
15:22:51.805 [pool-1-thread-1] DEBUG org.dcm4che3.net.Association - /127.0.0.1:11118<-/127.0.0.1:53116(1): enter state: Sta2 - Transport connection open
15:22:51.807 [pool-1-thread-1] DEBUG org.dcm4che3.net.Connection - Wait for connection on /127.0.0.1:11118
15:22:51.813 [pool-1-thread-2] INFO org.dcm4che3.net.Association - AIRKING<-MICRODICOM(1) >> A-ASSOCIATE-RQ
15:22:51.813 [pool-1-thread-2] DEBUG org.dcm4che3.net.Association - A-ASSOCIATE-RQ[
  calledAET: AIRKING
  callingAET: MICRODICOM
  applicationContext: 1.2.840.10008.3.1.1.1 - DICOM Application Context Name
  implClassUID: 1.2.276.0.7230010.3.0.3.6.7
  implVersionName: OFFIS_DCMTK_367
  maxPDULength: 16384
  maxOpsInvoked/maxOpsPerformed: 1/1
  PresentationContext[id: 1
    as: 1.2.840.10008.5.1.4.1.2.2.1 - Study Root Query/Retrieve Information Model - FIND
    ts: 1.2.840.10008.1.2.1 - Explicit VR Little Endian
    ts: 1.2.840.10008.1.2.2 - Explicit VR Big Endian (Retired)
    ts: 1.2.840.10008.1.2 - Implicit VR Little Endian
  ]
  PresentationContext[id: 3
    as: 1.2.840.10008.1.1 - Verification SOP Class
    ts: 1.2.840.10008.1.2.1 - Explicit VR Little Endian
    ts: 1.2.840.10008.1.2.2 - Explicit VR Big Endian (Retired)
    ts: 1.2.840.10008.1.2 - Implicit VR Little Endian
  ]
]
15:22:51.822 [pool-1-thread-2] DEBUG org.dcm4che3.net.Association - AIRKING<-MICRODICOM(1): enter state: Sta3 - Awaiting local A-ASSOCIATE response primitive
15:22:51.822 [pool-1-thread-2] INFO org.dcm4che3.net.Association - AIRKING<-MICRODICOM(1) << A-ASSOCIATE-AC
15:22:51.822 [pool-1-thread-2] DEBUG org.dcm4che3.net.Association - A-ASSOCIATE-AC[
  calledAET: AIRKING
  callingAET: MICRODICOM
  applicationContext: 1.2.840.10008.3.1.1.1 - DICOM Application Context Name
  implClassUID: 1.2.40.0.13.1.3
  implVersionName: dcm4che-5.21.0
  maxPDULength: 16378
  maxOpsInvoked/maxOpsPerformed: 1/1
  PresentationContext[id: 1
    result: 0 - acceptance
    ts: 1.2.840.10008.1.2.1 - Explicit VR Little Endian
  ]
  PresentationContext[id: 3
    result: 0 - acceptance
    ts: 1.2.840.10008.1.2.1 - Explicit VR Little Endian
  ]
]
15:22:51.823 [pool-1-thread-2] DEBUG org.dcm4che3.net.Association - AIRKING<-MICRODICOM(1): enter state: Sta6 - Association established and ready for data transfer
15:22:51.849 [pool-1-thread-2] INFO org.dcm4che3.net.Dimse - AIRKING<-MICRODICOM(1) >> 1:C-ECHO-RQ[pcid=3
  cuid=1.2.840.10008.1.1 - Verification SOP Class
  tsuid=1.2.840.10008.1.2.1 - Explicit VR Little Endian]
15:22:51.849 [pool-1-thread-2] DEBUG org.dcm4che3.net.Dimse - AIRKING<-MICRODICOM(1) >> 1:C-ECHO-RQ Command:
(0000,0002) UI [1.2.840.10008.1.1] AffectedSOPClassUID
(0000,0100) US [48] CommandField
(0000,0110) US [1] MessageID
(0000,0800) US [257] CommandDataSetType

15:22:51.866 [pool-1-thread-2] INFO org.dcm4che3.net.Association - AIRKING<-MICRODICOM(1): processing 1:C-ECHO-RQ[pcid=3
  cuid=1.2.840.10008.1.1 - Verification SOP Class
  tsuid=1.2.840.10008.1.2.1 - Explicit VR Little Endian] failed. Caused by:	
org.dcm4che3.net.service.DicomServiceException: null
	at org.dcm4che3.net.service.DicomServiceRegistry.lookupService(DicomServiceRegistry.java:126)
	at org.dcm4che3.net.service.DicomServiceRegistry.onDimseRQ(DicomServiceRegistry.java:86)
	at org.dcm4che3.net.ApplicationEntity.onDimseRQ(ApplicationEntity.java:474)
	at org.dcm4che3.net.Association.onDimseRQ(Association.java:746)
	at org.dcm4che3.net.PDUDecoder.decodeDIMSE(PDUDecoder.java:478)
	at org.dcm4che3.net.Association.handlePDataTF(Association.java:729)
	at org.dcm4che3.net.State$4.onPDataTF(State.java:103)
	at org.dcm4che3.net.Association.onPDataTF(Association.java:725)
	at org.dcm4che3.net.PDUDecoder.nextPDU(PDUDecoder.java:177)
	at org.dcm4che3.net.Association$2.run(Association.java:562)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
15:22:51.868 [pool-1-thread-2] INFO org.dcm4che3.net.Dimse - AIRKING<-MICRODICOM(1) << 1:C-ECHO-RSP[pcid=3, status=122H
  tsuid=1.2.840.10008.1.2.1 - Explicit VR Little Endian]
15:22:51.868 [pool-1-thread-2] DEBUG org.dcm4che3.net.Dimse - AIRKING<-MICRODICOM(1) << 1:C-ECHO-RSP Command:
(0000,0100) US [32816] CommandField
(0000,0120) US [1] MessageIDBeingRespondedTo
(0000,0800) US [257] CommandDataSetType
(0000,0900) US [290] Status

15:22:51.870 [pool-1-thread-2] INFO org.dcm4che3.net.Dimse - AIRKING<-MICRODICOM(1) >> 2:C-FIND-RQ[pcid=1, prior=0
  cuid=1.2.840.10008.5.1.4.1.2.2.1 - Study Root Query/Retrieve Information Model - FIND
  tsuid=1.2.840.10008.1.2.1 - Explicit VR Little Endian]
15:22:51.870 [pool-1-thread-2] DEBUG org.dcm4che3.net.Dimse - AIRKING<-MICRODICOM(1) >> 2:C-FIND-RQ Command:
(0000,0002) UI [1.2.840.10008.5.1.4.1.2.2.1] AffectedSOPClassUID
(0000,0100) US [32] CommandField
(0000,0110) US [2] MessageID
(0000,0700) US [0] Priority
(0000,0800) US [1] CommandDataSetType

15:22:51.870 [pool-1-thread-2] DEBUG org.dcm4che3.net.Dimse - AIRKING<-MICRODICOM(1) >> 2:C-FIND-RQ Dataset receiving...
15:22:51.870 [pool-1-thread-2] INFO org.dcm4che3.net.Association - AIRKING<-MICRODICOM(1): processing 2:C-FIND-RQ[pcid=1, prior=0
  cuid=1.2.840.10008.5.1.4.1.2.2.1 - Study Root Query/Retrieve Information Model - FIND
  tsuid=1.2.840.10008.1.2.1 - Explicit VR Little Endian] failed. Caused by:	
org.dcm4che3.net.service.DicomServiceException: null
	at org.dcm4che3.net.service.DicomServiceRegistry.lookupService(DicomServiceRegistry.java:126)
	at org.dcm4che3.net.service.DicomServiceRegistry.onDimseRQ(DicomServiceRegistry.java:86)
	at org.dcm4che3.net.ApplicationEntity.onDimseRQ(ApplicationEntity.java:474)
	at org.dcm4che3.net.Association.onDimseRQ(Association.java:746)
	at org.dcm4che3.net.PDUDecoder.decodeDIMSE(PDUDecoder.java:467)
	at org.dcm4che3.net.Association.handlePDataTF(Association.java:729)
	at org.dcm4che3.net.State$4.onPDataTF(State.java:103)
	at org.dcm4che3.net.Association.onPDataTF(Association.java:725)
	at org.dcm4che3.net.PDUDecoder.nextPDU(PDUDecoder.java:177)
	at org.dcm4che3.net.Association$2.run(Association.java:562)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
15:22:51.870 [pool-1-thread-2] INFO org.dcm4che3.net.Dimse - AIRKING<-MICRODICOM(1) << 2:C-FIND-RSP[pcid=1, status=122H
  tsuid=1.2.840.10008.1.2.1 - Explicit VR Little Endian]
15:22:51.870 [pool-1-thread-2] DEBUG org.dcm4che3.net.Dimse - AIRKING<-MICRODICOM(1) << 2:C-FIND-RSP Command:
(0000,0100) US [32800] CommandField
(0000,0120) US [2] MessageIDBeingRespondedTo
(0000,0800) US [257] CommandDataSetType
(0000,0900) US [290] Status

15:22:51.870 [pool-1-thread-2] DEBUG org.dcm4che3.net.Association - AIRKING<-MICRODICOM(1): Service User did not consume 154 bytes of DIMSE data.
15:22:51.870 [pool-1-thread-2] INFO org.dcm4che3.net.Association - AIRKING<-MICRODICOM(1) >> A-RELEASE-RQ
15:22:51.870 [pool-1-thread-2] DEBUG org.dcm4che3.net.Association - AIRKING<-MICRODICOM(1): enter state: Sta8 - Awaiting local A-RELEASE response primitive
15:22:51.870 [pool-1-thread-2] INFO org.dcm4che3.net.Association - AIRKING<-MICRODICOM(1) << A-RELEASE-RP
15:22:51.871 [pool-1-thread-2] DEBUG org.dcm4che3.net.Association - AIRKING<-MICRODICOM(1): enter state: Sta13 - Awaiting Transport Connection Close Indication
15:22:51.871 [pool-1-thread-2] INFO org.dcm4che3.net.Association - AIRKING<-MICRODICOM(1): i/o exception: java.io.IOException: Unexpected Error in State: Sta13 - Awaiting Transport Connection Close Indication
15:22:51.871 [pool-1-thread-2] INFO org.dcm4che3.net.Association - AIRKING<-MICRODICOM(1): close Socket[addr=/127.0.0.1,port=53116,localport=11118]
15:22:51.871 [pool-1-thread-2] DEBUG org.dcm4che3.net.Association - AIRKING<-MICRODICOM(1): enter state: Sta1 - Idle

 

...全文
1153 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_41871293 2025-01-23
  • 打赏
  • 举报
回复

在使用Dcm4che实现CFindSCP以及CMoveSCP时,可能会遇到一些挑战。首先,确保你的服务端正确地注册了CFindSCP和CMoveSCP服务。在你的代码中,你已经创建了BasicCFindSCPBasicCMoveSCP的实例,并将它们添加到了DicomServiceRegistry中,这是正确的做法。然而,空指针异常可能表明在处理请求时某些对象没有被正确初始化。

为了解决这个问题,你需要检查以下几点:

配图

  1. 确保DeviceApplicationEntityConnection对象都被正确初始化并配置。
  2. 检查DicomServiceRegistry是否正确地注册了所有的DICOM服务。

    配图

  3. 在处理C-Find和C-Move请求时,确保你正确地实现了业务逻辑,特别是在构造响应时。
  4. 确保你的服务端能够正确地处理传入的DICOM数据集,并且在发送响应之前已经完全准备好。

配图


以下是一些推荐的书籍,这些书籍可以帮助你更深入地理解DICOM标准以及如何使用Dcm4che实现DICOM服务:

推荐书籍图书特点
《DICOM PS3.6 - Data Dictionary》作者:NEMA,出版社:National Electrical Manufacturers Association,这本书是DICOM标准的官方文档,详细定义了DICOM数据字典,对于理解DICOM标签和属性至关重要。
《DICOM PS3.7 - Data Transfer》作者:NEMA,出版社:National Electrical Manufacturers Association,这本书描述了DICOM网络协议和数据传输机制,对于实现DICOM服务的开发者来说是必读的。
《Mastering DCM4Che》作者:Gonzalo Peña,出版社:Packt Publishing,这本书提供了对Dcm4che框架的全面介绍,包括如何使用它来实现各种DICOM服务,如C-Find和C-Move。
《DICOM for Programmers》作者:Ronald M. McDonald,出版社:O'Reilly Media,这本书面向程序员,讲解了如何在软件中集成和使用DICOM标准,包括与Dcm4che相关的实践指导。

在这些书籍中,《Mastering DCM4Che》可能是最直接相关的,因为它专门针对Dcm4che框架。它不仅介绍了框架的基本概念,还提供了实际的代码示例和最佳实践,这对于解决你在实现CFindSCP和CMoveSCP时遇到的问题非常有帮助。而《DICOM PS3.6》和《DICOM PS3.7》则是理解DICOM标准的基石,它们提供了必要的背景知识,帮助你深入理解DICOM协议的细节。最后,《DICOM for Programmers》则更多地从编程的角度出发,介绍了如何在不同的环境中使用DICOM标准。

在比较这些书籍时,你可以根据自己的需求和背景选择最合适的一本或几本。如果你是DICOM初学者,可能需要从基础的DICOM标准和数据字典开始学习,然后再深入学习Dcm4che框架。如果你已经有了一定的DICOM知识,那么直接阅读《Mastering DCM4Che》可能会更加高效。

已隐藏部分内容,更多查看原文

baidu_34061782 2024-11-11
  • 打赏
  • 举报
回复

..............................................

ba1yu 2024-07-29
  • 打赏
  • 举报
回复

求助

viruslafee001 2024-10-12
  • 举报
回复
@ba1yu 请问解决了吗
ba1yu 2024-10-16
  • 举报
回复
@viruslafee001 解决了

51,411

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧