【问题标题】:Connecting to dcm4chee using dcm4che from a JAVA program从 JAVA 程序使用 dcm4che 连接到 dcm4chee
【发布时间】:2018-03-01 11:11:51
【问题描述】:

更新

我更深入地研究了 dcm4che 的源代码,发现如果有一个,就会抛出一个 IncompatibleConnectionException

  • “未安装”连接
  • 或协议类型未设置或不匹配。

我不知道“已安装”连接是什么意思,但这个标志可以手动设置,所以我将本地和远程连接都设置为true(甚至用getInstalled()检查它们是否它们已“安装”——是的,它们现在是——以前这个属性是null)。

关于协议,它们没有被指定,所以对于这两个连接,我将它们设置为DICOM

结果:我仍然得到相同的异常。


我想使用dcm4che (5.12.0) 工具包在dcm4chee (2.18.3) 和我的JAVA 应用程序之间建立DICOM 关联。

问题是它似乎没有任何关于如何在 JAVA 应用程序中使用 dcm4che 的文档,所以我所能做的就是阅读 dcm4che 的源代码并尝试找出它的类和方法的用途,但我被困住了。如果有人已经有一个工作示例,那将非常有帮助。

到目前为止我有:

import org.dcm4che3.net.ApplicationEntity;
import org.dcm4che3.net.Association;
import org.dcm4che3.net.Connection;
import org.dcm4che3.net.Device;
import org.dcm4che3.net.pdu.AAssociateRQ;
import org.dcm4che3.net.pdu.PresentationContext;

...

ApplicationEntity locAE = new ApplicationEntity();
locAE.setAETitle("THIS_JAVA_APP");

Connection localConn = new Connection();
localConn.setCommonName("loc_conn");
localConn.setHostname("localhost");
localConn.setPort(11112);
localConn.setProtocol(Connection.Protocol.DICOM);
localConn.setInstalled(true);
locAE.addConnection(localConn);

ApplicationEntity remAE = new ApplicationEntity();
remAE.setAETitle("DCM4CHEE");

Connection remoteConn = new Connection();
remoteConn.setCommonName("rem_conn");
remoteConn.setHostname("localhost");
remoteConn.setPort(11112);
remoteConn.setProtocol(Connection.Protocol.DICOM);
remoteConn.setInstalled(true);
remAE.addConnection(remoteConn);

AAssociateRQ assocReq = new AAssociateRQ();
assocReq.setCalledAET(remAE.getAETitle());
assocReq.setCallingAET(locAE.getAETitle());
assocReq.setApplicationContext("1.2.840.10008.3.1.1.1");
assocReq.setImplClassUID("1.2.40.0.13.1.3");
assocReq.setImplVersionName("dcm4che-5.12.0");
assocReq.setMaxPDULength(16384);
assocReq.setMaxOpsInvoked(0);
assocReq.setMaxOpsPerformed(0);
assocReq.addPresentationContext(new PresentationContext(
    1, "1.2.840.10008.1.1", "1.2.840.10008.1.2"));

Device device = new Device("device");
device.addConnection(localConn);
device.addApplicationEntity(locAE);

Association assoc = locAE.connect(remAE, assocReq);

但我不知道我是否走在正确的道路上。

我得到的错误:

org.dcm4che3.net.IncompatibleConnectionException: No compatible connection to DCM4CHEE available on THIS_JAVA_APP
at org.dcm4che3.net.ApplicationEntity.findCompatibelConnection(ApplicationEntity.java:646)
at org.dcm4che3.net.ApplicationEntity.connect(ApplicationEntity.java:651)

【问题讨论】:

  • 我认为作为 SCU,您必须使用指定传输语法的构造函数:public PresentationContext(int pcid, String as, String... tss)。结果将由 SCP (dcm4chee) 填写
  • @kritzel_sw 你知道String as 代表什么吗?现在我有PresentationContext(1, "?", "1.2.840.10008.1.2")。我应该用什么代替??其他两个参数是否正确?
  • 我不得不猜测。但我很有信心,它应该是:PresentationContext(ID, AbstractSyntax (=Verification), TransferSyntax(es)), e.g. PresentationContext(1, "1.2.840.10008.1.1", "1.2.840.10008.1.2")
  • @kritzel_sw 它也不是这样工作的。同样的例外。不过还是谢谢啦,我会继续找的……
  • 我也更新了我的答案。也许从localConn 中删除参数,看看会发生什么。

标签: java dicom dcm4che


【解决方案1】:

您的设置中是否缺少Device 实例?看来,您需要一个Device,并附上ApplicationEntityConnection

查看来自 dcm4che 源的 FindSCU.java 源。

private final Device device = new Device("findscu");
private final ApplicationEntity ae = new ApplicationEntity("FINDSCU");
private final Connection conn = new Connection();

public FindSCU() throws IOException {
    device.addConnection(conn);
    device.addApplicationEntity(ae);
    ae.addConnection(conn);
}

我还认为,也许本地 Connection 对象可以在没有任何参数的情况下实例化,如 FindSCU 示例所示。也许参数以某种方式混淆了它,特别是考虑到您有指向localhost:11112的本地和远程连接。

但是,是的,必须同意,dcm4che3 API 的文档完全不够。

【讨论】:

  • 谢谢,同时我也意识到可能需要一个设备,因为我找到了an older implementation 用于关联,并且还根据我发现的其他一些论坛主题(@987654323)在请求中添加了一些其他参数@ 和 this) 所以我相应地更新了我的问题。不幸的是,我仍然不走运。
  • 我从新的异常中假设,操作的顺序似乎很重要。先将Connection 添加到Device,然后再添加ApplicationEntity
  • 谢谢,你是对的,现在Device 可以了(问题已更新)。所以现在我有一个Device,我只需要弄清楚它的用途...... :)
【解决方案2】:

这是工作代码:(我不知道这是否是最小的解决方案,请随意尝试...)

ApplicationEntity locAE = new ApplicationEntity();
locAE.setAETitle("THIS_JAVA_APP");
locAE.setInstalled(true);

Connection localConn = new Connection();
localConn.setCommonName("loc_conn");
localConn.setHostname("localhost");
localConn.setPort(11112);
localConn.setProtocol(Connection.Protocol.DICOM);
localConn.setInstalled(true);
locAE.addConnection(localConn);

ApplicationEntity remAE = new ApplicationEntity();
remAE.setAETitle("DCM4CHEE");
remAE.setInstalled(true);

Connection remoteConn = new Connection();
remoteConn.setCommonName("rem_conn");
remoteConn.setHostname("localhost");
remoteConn.setPort(11112);
remoteConn.setProtocol(Connection.Protocol.DICOM);
remoteConn.setInstalled(true);
remAE.addConnection(remoteConn);

AAssociateRQ assocReq = new AAssociateRQ();
assocReq.setCalledAET(remAE.getAETitle());
assocReq.setCallingAET(locAE.getAETitle());
assocReq.setApplicationContext("1.2.840.10008.3.1.1.1");
assocReq.setImplClassUID("1.2.40.0.13.1.3");
assocReq.setImplVersionName("dcm4che-5.12.0");
assocReq.setMaxPDULength(16384);
assocReq.setMaxOpsInvoked(0);
assocReq.setMaxOpsPerformed(0);
assocReq.addPresentationContext(new PresentationContext(
    1, "1.2.840.10008.1.1", "1.2.840.10008.1.2"));

Device device = new Device("device");
device.addConnection(localConn);
device.addApplicationEntity(locAE);

Executor exec = (Runnable command) -> {};
device.setExecutor(exec);

Association assoc = locAE.connect(localConn, remoteConn, assocReq);

以及相关的dcm4chee日志:

2018-03-02 23:21:42,832 INFO  THIS_JAVA_APP->DCM4CHEE (TCPServer-1) [org.dcm4cheri.net.FsmImpl] received AAssociateRQ
    appCtxName: 1.2.840.10008.3.1.1.1/DICOM Application Context Name
    implClass:  1.2.40.0.13.1.3
    implVersion:    dcm4che-5.12.0
    calledAET:  DCM4CHEE
    callingAET: THIS_JAVA_APP
    maxPDULen:  16378
    asyncOpsWindow: 
    pc-1:   as=1.2.840.10008.1.1/Verification SOP Class
        ts=1.2.840.10008.1.2/Implicit VR Little Endian
2018-03-02 23:21:42,843 INFO  THIS_JAVA_APP->DCM4CHEE (TCPServer-1) [org.dcm4cheri.net.FsmImpl] sending AAssociateAC
    appCtxName: 1.2.840.10008.3.1.1.1/DICOM Application Context Name
    implClass:  1.2.40.0.13.1.1.1
    implVersion:    dcm4che-1.4.34
    calledAET:  DCM4CHEE
    callingAET: THIS_JAVA_APP
    maxPDULen:  16352
    asyncOpsWindow: 
    pc-1:   0 - acceptance
        ts=1.2.840.10008.1.2/Implicit VR Little Endian

建立关联后,see this other post 了解如何执行 C-FIND。

【讨论】:

    【解决方案3】:

    编辑

    显然,我解决了这个问题。从

    更改执行者
    Executor exec = (Runnable command) -> {};
    device.setExecutor(exec);
    

    ExecutorService executorService = Executors.newSingleThreadExecutor();
    ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
    device.setExecutor(executorService);
    device.setScheduledExecutor(scheduledExecutorService);
    

    这样我的应用程序正确地收到了来自服务器的关联响应。这可以作为其他人的参考。

    感谢您分享您的代码。这对我真的很有帮助。

    原帖

    我无法使用与您提出的解决方案类似的代码执行连接。我正在尝试请求将 dcm4chee-arc-light 与 dcm4che(均为 5.14.1)关联,我有如下内容:

    Device device = new Device(deviceName);
    ApplicationEntity locAE = new ApplicationEntity(localAE);
    Connection conn = new Connection();
    Connection remote = new Connection();
    AAssociateRQ rq = new AAssociateRQ();
    
    device.addConnection(conn);
    device.addApplicationEntity(locAE);
    locAE.addConnection(conn);
    
    ApplicationEntity remAE = new ApplicationEntity();
    remAE.setAETitle(remoteAE);
    
    remote.setCommonName("rem_conn");
    remote.setHostname(remoteIP);
    remote.setPort(remotePort);
    remote.setProtocol(Connection.Protocol.DICOM);
    remAE.addConnection(remote);
    
    rq.setCalledAET(remAE.getAETitle());
    rq.setCallingAET(locAE.getAETitle());
    rq.setApplicationContext("1.2.840.10008.3.1.1.1");
    rq.setImplClassUID("1.2.40.0.13.1.3");
    rq.setImplVersionName("dcm4che-5.14.1");
    rq.setMaxPDULength(16384);
    rq.setMaxOpsInvoked(0);
    rq.setMaxOpsPerformed(0);
    rq.addPresentationContext(new PresentationContext(
            1, "1.2.840.10008.5.1.4.1.2.2.1", "1.2.840.10008.1.2"));
    
    Executor exec = (Runnable command) -> {};
    device.setExecutor(exec);
    
    //Opens association and connects to remote server
    Association as = locAE.connect(conn, remote, rq);
    

    但是在尝试连接到远程 AET 时,它似乎没有收到来自远程 AET 的 AAssociation 响应。我的 Java 应用程序在 Sta5 中挂起(等待关联响应),而服务器在 Sta6 中挂起(准备好进行数据传输)。

    Java 日志:

    [main] INFO org.dcm4che3.net.Connection  - Initiate connection from 0.0.0.0/0.0.0.0:0 to localhost:11112
    [main] INFO org.dcm4che3.net.Connection  - Established connection Socket[addr=localhost/127.0.0.1,port=11112,localport=50101]
    [main] DEBUG org.dcm4che3.net.Association  - /127.0.0.1:50101>localhost/127.0.0.1:11112(1): enter state: Sta4 - Awaiting transport connection opening to complete
    [main] INFO org.dcm4che3.net.Association  - DEVICEAE->DCMQRSCP(1) << A-ASSOCIATE-RQ
    [main] DEBUG org.dcm4che3.net.Association  - A-ASSOCIATE-RQ[
      calledAET: DCMQRSCP
      callingAET: DEVICEAE
      applicationContext: 1.2.840.10008.3.1.1.1 - DICOM Application Context Name
      implClassUID: 1.2.40.0.13.1.3
      implVersionName: dcm4che-5.14.1
      maxPDULength: 16378
      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 - Implicit VR Little Endian
     ]
    ]
    [main] DEBUG org.dcm4che3.net.Association  - DEVICEAE->DCMQRSCP(1): enter state: Sta5 - Awaiting A-ASSOCIATE-AC or A-ASSOCIATE-RJ PDU
    

    服务器日志:

    19:11:29,397 INFO  - Accept connection Socket[addr=/127.0.0.1,port=50101,localport=11112]
    19:11:29,397 DEBUG - /127.0.0.1:11112<-/127.0.0.1:50101(3): enter state: Sta2 - Transport connection open
    19:11:29,416 INFO  - DCMQRSCP<-DEVICEAE(3) >> A-ASSOCIATE-RQ
    19:11:29,416 DEBUG - A-ASSOCIATE-RQ[
     calledAET: DCMQRSCP
     callingAET: DEVICEAE
     applicationContext: 1.2.840.10008.3.1.1.1 - DICOM Application Context Name
     implClassUID: 1.2.40.0.13.1.3
     implVersionName: dcm4che-5.14.1
     maxPDULength: 16378
     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 - Implicit VR Little Endian
      ]
     ]
    19:11:29,419 DEBUG - DCMQRSCP<-DEVICEAE(3): enter state: Sta3 - Awaiting local A-ASSOCIATE response primitive
    19:11:29,419 INFO  - DCMQRSCP<-DEVICEAE(3) << A-ASSOCIATE-AC
    19:11:29,419 DEBUG - A-ASSOCIATE-AC[
     calledAET: DCMQRSCP
     callingAET: DEVICEAE
     applicationContext: 1.2.840.10008.3.1.1.1 - DICOM Application Context Name
     implClassUID: 1.2.40.0.13.1.3
     implVersionName: dcm4che-5.14.1
     maxPDULength: 16378
     maxOpsInvoked/maxOpsPerformed: 1/1
     PresentationContext[id: 1
     result: 0 - acceptance
     ts: 1.2.840.10008.1.2 - Implicit VR Little Endian
      ]
     ]
    19:11:29,427 DEBUG - DCMQRSCP<-DEVICEAE(3): enter state: Sta6 - Association established and ready for data transfer
    

    我觉得我错过了什么,但我找不到问题的根源。感谢任何帮助,因为我还是 dcm4che 和 DICOM 协议的新手。

    谢谢。

    【讨论】:

    • 这并没有提供问题的答案。您可以search for similar questions,或参考页面右侧的相关和链接问题找到答案。如果您有一个相关但不同的问题,ask a new question,并包含指向此问题的链接以帮助提供上下文。见:Ask questions, get answers, no distractions
    • @Filnor,它最初没有提供答案,但它是针对给定答案的——这在我的情况下不起作用。在确定问题后,我最终对这个问题给出了不同的答案,这个答案可能适用于遇到与我相同的问题的人。我觉得在这里有这个比在引用这个的问题中更有用,因为人们将来更容易看到它。
    猜你喜欢
    • 1970-01-01
    • 2021-05-10
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-25
    相关资源
    最近更新 更多