Calarence 2019-02-15 09:07 采纳率: 0%
浏览 1027
已结题

DCMTK 获取服务端的某一患者序列 并传输至本地

最近在研究DCMTK,目的是通过输入患者ID或者姓名,获取到该患者的序列并传输到本地。
目前已经安装好DCMTK库,使用ConquestDICOMServer构建了服务端,去查询信息时用到了 ASC_addPresentationContext(params, presentationContextID,
UID_FINDStudyRootQueryRetrieveInformationModel,

            ,但是输出的结果在服务端打印如下:     
        [CONQUESTSRV1]  Calling Application Title : "CONQUESTSRV1    "

[CONQUESTSRV1] Called Application Title : "CONQUESTSRV1 "
[CONQUESTSRV1] Application Context : "1.2.840.10008.3.1.1.1", PDU length: 16384
[CONQUESTSRV1] Presentation Context 0 "1.2.840.10008.5.1.4.1.2.2.1" 1
[CONQUESTSRV1] **(StudyRootQuery) search level: **
[CONQUESTSRV1] C-Find (StudyRoot) located 0 records
CONQUESTSRV1 search level:
[CONQUESTSRV1] C-Find (StudyRoot) located 0 records

问题点:1. search level 没有值;
2.应用上下文,描述上下文是否添加正确;
3.服务端和客户端的编码方案是否存在问题。

主要代码附:

OFCmdUnsignedInt maxXferSyntaxes = OFstatic_cast(OFCmdUnsignedInt, (DIM_OF(transferSyntaxes)));

T_ASC_Network *net;
T_ASC_Parameters *params;
DIC_NODENAME localHost;
DIC_NODENAME peerHost;
T_ASC_Association *assoc;
OFString temp_str;


WSAData winSockData;
/* we need at least version 1.1 */
WORD winSockVersionNeeded = MAKEWORD( 1, 1 );
WSAStartup(winSockVersionNeeded, &winSockData);
if (!dcmDataDict.isDictionaryLoaded())
{
    printf("No data dictionary loaded, check environment variable\n");
}
 /* initialize network, i.e. create an instance of T_ASC_Network*. */
OFCondition cond = ASC_initializeNetwork(NET_REQUESTOR, 0, 30, &net);
if (cond.bad()) 
{
    return DCMLIB_E_UNEXPECTED;
}

/* initialize asscociation parameters, i.e. create an instance of T_ASC_Parameters*. */
cond = ASC_createAssociationParameters(&params, ASC_DEFAULTMAXPDU);
if (cond.bad()) 
{
    return DCMLIB_E_UNEXPECTED;
}

/* sets this application's title and the called application's title in the params */
/* structure. The default values to be set here are "STORESCU" and "ANY-SCP". */
ASC_setAPTitles(params, opt_ourTitle.c_str(), opt_peerTitle.c_str(), NULL);

/* Set the transport layer type (type of network connection) in the params */
/* strucutre. The default is an insecure connection; where OpenSSL is  */
/* available the user is able to request an encrypted,secure connection. */
cond = ASC_setTransportLayerType(params, OFFalse);
if (cond.bad()) 
{
    return DCMLIB_E_UNEXPECTED;
}

/* Figure out the presentation addresses and copy the */
/* corresponding values into the association parameters.*/
gethostname(localHost, sizeof(localHost) - 1);
sprintf_s(peerHost, "%s:%d", opt_peer.c_str(), OFstatic_cast(int, opt_port));
ASC_setPresentationAddresses(params, localHost, peerHost);

/* Set the presentation contexts which will be negotiated */
/* when the network connection will be established */
int presentationContextID = 1; /* odd byte value 1, 3, 5, .. 255 */

for (unsigned long ii=0; ii<1; ii++)
{
    cond = ASC_addPresentationContext(params, presentationContextID,
        UID_FINDStudyRootQueryRetrieveInformationModel,
        transferSyntaxes, OFstatic_cast(int,1));
    presentationContextID += 2;
    if (cond.bad())
    {
         return DCMLIB_E_UNEXPECTED;
    }
}

/* create association, i.e. try to establish a network connection to another */
/* DICOM application. This call creates an instance of T_ASC_Association*. */
cond = ASC_requestAssociation(net, params, &assoc);
 if (cond.bad()) 
{
    if (cond == DUL_ASSOCIATIONREJECTED)
    {
        T_ASC_RejectParameters rej;

        ASC_getRejectParameters(params, &rej);      
    } 
    ASC_destroyAssociation(&assoc);
    ASC_dropNetwork(&net);
    WSACleanup();
    return DCMLIB_E_SERVER_NOT_RESPONE;
}

/* count the presentation contexts which have been accepted by the SCP */
/* If there are none, finish the execution */
if (ASC_countAcceptedPresentationContexts(params) == 0) 
{
    ASC_destroyAssociation(&assoc);
    ASC_dropNetwork(&net);
    WSACleanup();
    return DCMLIB_E_SERVER_NOT_RESPONE;
}

/* do the real work, i.e. send a number of C-ECHO-RQ messages to the DICOM application */
/* this application is connected with and handle corresponding C-ECHO-RSP messages. */

// cond = cecho(assoc, 1);

T_ASC_PresentationContextID presID;
T_DIMSE_C_FindRQ req;
T_DIMSE_C_FindRSP rsp;
DcmFileFormat dcmff;
const char* abstractSyntax = UID_FINDStudyRootQueryRetrieveInformationModel;
presID = ASC_findAcceptedPresentationContextID(assoc, abstractSyntax);
if (presID == 0)
{
    printf("No presentation context\n");
    return -8;
}
//8)发起C-FIND请求
//8.1)准备C-FIND-RQ message
bzero(OFreinterpret_cast(char*, &req), sizeof(req));//内存初始化为空;
strcpy_s(req.AffectedSOPClassUID, abstractSyntax);
req.DataSetType = DIMSE_DATASET_PRESENT;
req.Priority = DIMSE_PRIORITY_LOW;
//设置要查询的信息为空时,待会儿查询结果中会返回
DcmDataset* dataset = new DcmDataset();
InsertQueryItems(dataset, "","*8");

ZSCFindCallback zsCallback;
DcmFindSCUCallback* callback = &zsCallback;
callback->setAssociation(assoc);
callback->setPresentationContextID(presID);
/* as long as no error occured and the counter does not equal 0 */
cond = EC_Normal;
int rescout = 1;
while (cond.good())
{
    DcmDataset *statusDetail = NULL;

    /* complete preparation of C-FIND-RQ message */
    req.MessageID = assoc->nextMsgID++;

    /* finally conduct transmission of data */

    cond = DIMSE_findUser(assoc, presID, &req, dataset,
        rescout,progressCallback, callback, DIMSE_BLOCKING, 30,
        &rsp, &statusDetail);
    //设置了查询采用阻塞模式,DIMSE_BLOCKING
    //设置连接超时为50



    /*
    *添加异常判别
    *
    */
    //cond = EC_EndOfStream;//假设异常,返回
}

/* tear down association, i.e. terminate network connection to SCP */
if (cond == EC_Normal)
{
    /* release association */
    cond = ASC_releaseAssociation(assoc);
    if (cond.bad())
    {
        ASC_destroyAssociation(&assoc);
        ASC_dropNetwork(&net);
        WSACleanup();
        return DCMLIB_E_FAILED_TO_EXEC;
    }
}
else if (cond == DUL_PEERREQUESTEDRELEASE)
{
    cond = ASC_abortAssociation(assoc);
    if (cond.bad()) 
    {
        ASC_destroyAssociation(&assoc);
        ASC_dropNetwork(&net);
        WSACleanup();
        return DCMLIB_E_FAILED_TO_EXEC;
    }
}
else if (cond == DUL_PEERABORTEDASSOCIATION)
{
}
else
{
    cond = ASC_abortAssociation(assoc);
    if (cond.bad()) 
    {
        ASC_destroyAssociation(&assoc);
        ASC_dropNetwork(&net);
        WSACleanup();
        return DCMLIB_E_FAILED_TO_EXEC;
    }
}

/* destroy the association, i.e. free memory of T_ASC_Association* structure. This */
/* call is the counterpart of ASC_requestAssociation(...) which was called above. */
cond = ASC_destroyAssociation(&assoc);
if (cond.bad()) 
{
    return DCMLIB_E_FAILED_TO_EXEC;
}

/* drop the network, i.e. free memory of T_ASC_Network* structure. This call */
/* is the counterpart of ASC_initializeNetwork(...) which was called above. */
cond = ASC_dropNetwork(&net);
if (cond.bad()) 
{
    return DCMLIB_E_ACCESS_DENIED;
}

WSACleanup();


return DCMLIB_S_OK;
  • 写回答

1条回答 默认 最新

  • Calarence 2021-09-29 11:47
    关注

    已经超过时间不能结题了

    评论

报告相同问题?

悬赏问题

  • ¥20 iqoo11 如何下载安装工程模式
  • ¥15 本题的答案是不是有问题
  • ¥15 关于#r语言#的问题:(svydesign)为什么在一个大的数据集中抽取了一个小数据集
  • ¥15 C++使用Gunplot
  • ¥15 这个电路是如何实现路灯控制器的,原理是什么,怎么求解灯亮起后熄灭的时间如图?
  • ¥15 matlab数字图像处理频率域滤波
  • ¥15 在abaqus做了二维正交切削模型,给刀具添加了超声振动条件后输出切削力为什么比普通切削增大这么多
  • ¥15 ELGamal和paillier计算效率谁快?
  • ¥15 蓝桥杯单片机第十三届第一场,整点继电器吸合,5s后断开出现了问题
  • ¥15 file converter 转换格式失败 报错 Error marking filters as finished,如何解决?