# include“ltdic.h”
L_INTLDicomNet: SendCStoreRequest(nPresentationID, nMessageID, pszClass, pszInstance, nPriority, pszMoveAE, nMoveMessageID, pDS)
发送一个C-STORE-REQ发送给连接的对等成员的消息。该函数可在pac成像工具包。
表示ID。表示ID提供有关数据的类类型和传输数据时使用的传输语法的信息。
消息ID。连接的成员发送的每条消息都应该有唯一的ID。由于连接的成员可以发送多条消息,因此此ID允许该成员识别特定请求何时完成。
受请求影响的类。这将是一个SOP类或SOP元类。
类的实例。例如,一个服务器可能有三个核医学类实例。该值标识具有特定实例的数据。
消息的优先级。服务类提供者可能支持,也可能不支持优先级。因此,设置该参数可能有效果,也可能没有效果。可能取值为:
价值 | 意义 |
---|---|
COMMAND_PRIORITY_LOW | [0x0002]低优先级消息。 |
COMMAND_PRIORITY_MEDIUM | [0x0000]中等优先级消息。 |
COMMAND_PRIORITY_HIGH | [0x0001]高优先级消息。 |
字符串,包含最初请求移动的应用程序实体的名称。对于从客户端到服务器的简单存储请求,这应该是“。当请求是C-MOVE的子操作时,这将包含请求移动的AE的名称。
原始移动请求消息的ID。对于从客户端到服务器的简单存储请求,这个值应该是0。当请求是C-MOVE的子操作时,它将包含C-MOVE请求的原始消息ID。
指向要存储的数据集的指针。
价值 | 意义 |
---|---|
0 | 成功 |
> 0 | 发生错误。指返回代码. |
当SCU请求移动(C-MOVE-REQ)时,SCP可能必须调用此函数来请求一个或多个C-STORE-REQ子操作以完成存储。C-MOVE-REQ中的一系列调用和信息传输是复杂的。有关更多信息,请参阅移动复合数据.
调用此函数将生成对LDicomNet: OnReceiveCStoreRequest在SCP上。SCP应该通过调用进行响应LDicomNet: SendCStoreResponse哪个将生成对的调用LDicomNet: OnReceiveCStoreResponse.
必需的dll和库
Win32, x64
这是一个基本但完整的示例,演示了DICOM客户机向服务器发送C-Store-REQ,服务器处理请求。
名称空间LDicomNet_SendCStoreRequest_Namespace
{
//记录消息
//这个实现记录到控制台和调试窗口
LogMessage(tsar *szMsg)
{
wprintf(文本(“\ n”));
wprintf (szMsg);
OutputDebugStringW(文本(“\ n”));
OutputDebugStringW (szMsg);
}
L_VOID LogMessage(TCHAR *s, L_INT n)
{
TCHAR szLog[200] = {0};
wsprintf (szLog文本(“% s (% d)”), s, n);
LogMessage (szLog);
}
L_VOID LogMessage(TCHAR *s, TCHAR *s2)
{
TCHAR szLog[200] = {0};
wsprintf (szLog文本(“% s (% s)”), s, s2);
LogMessage (szLog);
}
// *******************************************************************************************
//客户端类
//
//用于连接到服务器的类
// *******************************************************************************************
类CMyClient:公共LDicomNet
{
公共:
CMyClient(L_INT32): LDicomNet(NULL, nMode)
{
m_waitEvent = CreateEvent(NULL, TRUE, TRUE, TEXT(“ClientEvent”));
ResetEvent (m_waitEvent);
}
~ CMyClient (无效)
{
CloseHandle (m_waitEvent);
}
/ /客户端
L_VOID OnConnect(L_INT error);
OnReceiveAssociateAccept(LDicomAssociate *pPDU);
L_VOID OnReceiveReleaseResponse ();
L_VOID onreceivecstorerresponse (L_UCHAR nPresentationID, L_UINT16 nMessageID, L_TCHAR *pszClass, L_TCHAR *pszInstance, L_UINT16 nStatus);
等待(DWORD超时= 5000);
私人:
处理m_waitEvent;
};
//继续发送消息,直到hEvent发出信号,即我们的超时
//如果hEvent有信号则返回TRUE
//如果超时返回FALSE
L_BOOL MessageLoop (
处理hEvent,//需要等待的句柄
DWORD超时//超时时间,单位为毫秒
)
{
DWORD dwStart = GetTickCount();
MSG MSG = {0};
挥发性L_BOOL bRunForever = TRUE;
而(bRunForever)
{
如果(PeekMessage(&msg, NULL, 0,0, PM_REMOVE))
{
TranslateMessage(味精);
DispatchMessage(味精);
}
如果(WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0)
{
ResetEvent (hEvent);
返回真正的;
}
DWORD dwCurrent = GetTickCount();
如果((dwCurrent - dwStart) > timeout)
{
返回虚假的;
}
}
返回真正的;
}
CMyClient::OnConnect(L_INT error)
{
L_TCHAR szMsg[200] = {0};
wsprintf (szMsg文本(“CMyClient:: OnConnect: nError [% d]”), nError);
LogMessage (szMsg);
}
CMyClient::OnReceiveAssociateAccept(LDicomAssociate *pPDU)
{
UNREFERENCED_PARAMETER (pPDU);
LogMessage(文本(“CMyClient:: OnReceiveAssociateAccept”));
SetEvent (m_waitEvent);
}
CMyClient:: onreceivecstorerresponse (L_UCHAR nPresentationID, L_UINT16 nMessageID, L_TCHAR *pszClass, L_TCHAR *pszInstance, L_UINT16 nStatus)
{
如果(pszClass == NULL)
{
pszClass = TEXT("");
}
LogMessage(文本(“CMyClient:: OnReceiveCStoreResponse”));
LogMessage(文本(“\ t nPresentationID”), nPresentationID);
LogMessage(文本(“\ t nMessageID”), nMessageID);
LogMessage(文本(“\ t pszClass”), pszClass);
LogMessage(文本(“\ t pszInstance”), pszInstance);
开关(nStatus)
{
情况下COMMAND_STATUS_WARNING:
LogMessage(文本(“\t nStatus: COMMAND_STATUS_WARNING”));
打破;
情况下COMMAND_STATUS_PENDING_WARNING:
LogMessage(文本("\t nStatus: COMMAND_STATUS_PENDING_WARNING"));
打破;
情况下COMMAND_STATUS_PENDING:
LogMessage(文本(\t nStatus: COMMAND_STATUS_PENDING"));
打破;
情况下COMMAND_STATUS_SUCCESS:
LogMessage(文本(“\t nStatus: COMMAND_STATUS_SUCCESS”));
SetEvent (m_waitEvent);
打破;
情况下COMMAND_STATUS_REFUSED_OUT_OF_RESOURCES:
{
LogMessage(文本(\t nStatus: COMMAND_STATUS_REFUSED_OUT_OF_RESOURCES"));
//获取命令集中额外的元素
LDicomDS = GetCommandSet();
如果(pCS != NULL)
{
pDICOMELEMENT pElement = pCS->FindFirstElement(NULL, TAG_ERROR_COMMENT, TRUE);
如果(pElement != NULL)
{
L_TCHAR *pszErrorComment = pCS->GetStringValue(pElement, 0,1);
LogMessage(文本(\t ErrorComment: "), pszErrorComment);
}
}
}
SetEvent (m_waitEvent);
打破;
}
SetEvent (m_waitEvent);
}
L_VOID CMyClient: OnReceiveReleaseResponse ()
{
LogMessage(文本(“CMyClient:: OnReceiveReleaseResponse”));
SetEvent (m_waitEvent);
}
CMyClient::Wait(DWORD超时)
{
L_BOOL bRet = MessageLoop(m_waitEvent, timeout);
返回bRet;
}
// *******************************************************************************************
//服务器连接类
//
//当客户端连接时,CMyServer创建一个CMyServerConnection类的新实例
//并接受连接。
// *******************************************************************************************
类CMyServerConnection:公共LDicomNet
{
公共:
CMyServerConnection(L_INT32): LDicomNet(NULL, nMode)
{
}
~ CMyServerConnection (无效)
{
}
/ /服务器
(LDicomAssociate *pPDU);
L_VOID OnReceiveCStoreRequest(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_TCHAR *pszClass, L_TCHAR *pszInstance, L_UINT16 nPriority, L_TCHAR *pszMoveAE, L_UINT16 nMoveMessageID, LDicomDS *pDS);
L_VOID OnReceiveReleaseRequest ();
};
#定义SIZEINWORD (p)运算符(p) /运算符(L_TCHAR)
L_VOID CMyServerConnection::OnReceiveAssociateRequest
{
LogMessage(文本(“\ tCMyServerConnection:: OnReceiveAssociateRequest”));
LDicomAssociate DicomAssociate(假);
L_TCHAR clientAE[20] = {0};
pPDU - > GetCalling (clientAE 20);
//复制接收到的表示对象
//回复我们只支持接收到的hPDU的第一个传输语法
L_TCHAR szTransfer[PDU_MAX_UID_SIZE + 1] = {0};
[PDU_MAX_UID_SIZE + 1] = {0};
L_INT iPresentationCount = pPDU->GetPresentationCount();
为(L_UCHAR i = 0;i < iPresentationCount;我+ +)
{
L_UCHAR nId = pPDU->GetPresentation(i);
pPDU->GetTransfer(nId, 0, szTransfer, PDU_MAX_UID_SIZE + 1);
L_UCHAR nResult = PDU_ACCEPT_RESULT_SUCCESS;
pPDU->GetAbstract(nId, szAbstract, PDU_MAX_UID_SIZE + 1);
DicomAssociate。AddPresentation(nId, nResult, szAbstract);
DicomAssociate。, AddTransfer(国家免疫日szTransfer);
}
LogMessage(文本(“\ tCMyServerConnection:: SendAssociateAccept”));
SendAssociateAccept (&DicomAssociate);
}
L_VOID CMyServerConnection::OnReceiveCStoreRequest(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_TCHAR *pszClass, L_TCHAR *pszInstance, L_UINT16 nPriority, L_TCHAR *pszMoveAE, L_UINT16 nMoveMessageID, LDicomDS *pDS)
{
UNREFERENCED_PARAMETER (pDS);
UNREFERENCED_PARAMETER (pszMoveAE);
LogMessage(文本(“\ tCMyServerConnection:: OnReceiveCStoreRequest”));
LogMessage(文本(“\ t nMoveMessageID”), nMoveMessageID);
LogMessage(文本(“\ t nPriority”), nPriority);
/ /……
/ /……在这里开店
/ /……nStatus =存储的状态
LogMessage(文本(“\t\t做这里的商店”));
//发送C-Store-RSP
LogMessage(文本(“\ tCMyServerConnection:: SendCStoreResponse”));
sendcstorerresponse (nPresentationID, nMessageID, pszClass, pszInstance, COMMAND_STATUS_SUCCESS);
}
L_VOID CMyServerConnection: OnReceiveReleaseRequest ()
{
LogMessage(文本(“\ tCMyServerConnection:: OnReceiveReleaseRequest”));
LogMessage(文本(“\ tCMyServerConnection:: SendReleaseResponse”));
SendReleaseResponse ();
}
// *******************************************************************************************
//服务器类
//
//监听连接
//当客户端连接时,这个类创建一个CMyServerConnection并接受连接
// *******************************************************************************************
类CMyServer:公共LDicomNet
{
公共:
CMyServer(L_INT32): LDicomNet(NULL, nMode)
{
m_pServerConnection = NULL;
}
~ CMyServer (无效)
{
如果(m_pServerConnection = NULL)
{
删除m_pServerConnection;
}
}
L_VOID OnAccept(L_INT error);
L_VOID OnClose(L_INT nError, LDicomNet *pServerConnection);
CMyServerConnection * m_pServerConnection;
};
CMyServer::OnAccept(L_INT error)
{
LogMessage(文本(“\ tCMyServer:: OnAccept”));
如果(错误!= DICOM_SUCCESS)
{
返回;
}
如果(m_pServerConnection = NULL)
{
删除m_pServerConnection;
m_pServerConnection = NULL;
}
m_pServerConnection =新CMyServerConnection (DICOM_SECURE_NONE);
如果(m_pServerConnection == NULL)
{
返回;
}
/ / m_pServerConnection - > EnableOptimizedSend(真正的);
LDicomNet::Accept(m_pServerConnection);
如果(错误!= DICOM_SUCCESS)
{
删除m_pServerConnection;
返回;
}
}
L_VOID CMyServer::OnClose(L_INT nError, LDicomNet *pServerConnection)
{
UNREFERENCED_PARAMETER (nError);
LogMessage(文本(“\ tCMyServer:: OnClose”));
如果(m_pServerConnection == pServerConnection)
{
m_pServerConnection = NULL;
}
删除(CMyServerConnection *) pServerConnection;
}
// *******************************************************************************************
//从这里开始
// *******************************************************************************************
#定义WaitForProcessing() \
{\
如果(! client.Wait ()) \
{\
LogMessage(文本(“超时:客户端。连接”));\
nRet = DICOM_ERROR_NET_TIME_OUT;\
转到清理;\
} \
}
L_INT LDicomNet_SendCStoreRequestExample ()
{
LogMessage(文本("\n\n *** SendCStoreRequestExample ***"));
L_TCHAR *pszServerAddress = TEXT(“127.0.0.1”);
L_UINT uServerPort = 504;
L_INT nRet = DICOM_SUCCESS;
//加载客户端将要存储的DICOM数据集
LDicomDS ds;
// ds. loadd (MAKE_IMAGE_PATH(TEXT("IMAGE1.dcm")), DS_LOAD_CLOSE);
ds。LoadDS(文本(“d: \ \ \ \ image3.dcm图像”)), DS_LOAD_CLOSE);
L_TCHAR *pszStorageClass = NULL;
pDICOMELEMENT pElement = ds。FindFirstElement(NULL, TAG_MEDIA_STORAGE_SOP_CLASS_UID, TRUE);
如果(pElement != NULL)
{
pszStorageClass = ds。GetStringValue(pElement, 0,1);
}
如果(pszStorageClass == NULL || _tcslen(pszStorageClass) == 0)
{
pElement = ds。FindFirstElement(NULL, TAG_SOP_CLASS_UID, TRUE);
如果(pElement != NULL)
{
pszStorageClass = ds。GetStringValue(pElement, 0,1);
}
}
如果(pszStorageClass == NULL || _tcslen(pszStorageClass) == 0)
{
pszStorageClass = UID_CT_IMAGE_STORAGE;//默认为CT Image Storage
}
//
//获取图像传输语法
//
L_TCHAR *pszTransferSyntax = NULL;
L_TCHAR *pszStorageInstance = NULL;
pElement = ds。FindFirstElement(NULL, TAG_TRANSFER_SYNTAX_UID, TRUE);
如果(pElement != NULL)
{
pszTransferSyntax = ds。GetStringValue(pElement, 0,1);
}
pElement = ds。FindFirstElement(NULL, TAG_SOP_INSTANCE_UID, TRUE);
如果(pElement != NULL)
{
pszStorageInstance = ds。GetStringValue(pElement, 0,1);
}
LDicomNet:启动();
CMyClient客户机(DICOM_SECURE_NONE);
CMyServer服务器(DICOM_SECURE_NONE);
LogMessage(文本(“\ tCMyServer:听”));
nRet = server。监听(pszServerAddress, uServerPort, 5);
LogMessage(文本(“CMyClient:连接”));
客户端。Connect(NULL, 0, pszServerAddress, uServerPort);
如果(! client.Wait (2000))
{
如果(! client.IsConnected ())
{
LogMessage(文本(“超时:客户端。连接”));
nRet = DICOM_ERROR_NET_TIME_OUT;
转到清理;
}
}
如果(nRet == DICOM_SUCCESS)
{
//创建关联类作为请求
LDicomAssociate dicomAssociateRequest(真正的);
dicomAssociateRequest。SetCalled(文本(“L20_PACS_SCP32”));
dicomAssociateRequest。SetCalling(文本(“LEAD_CLIENT”));
dicomAssociateRequest。SetImplementClass(真的,文本(“1.2.840.114257.1”));
dicomAssociateRequest。SetImplementVersion(真的,文本(“1”));
dicomAssociateRequest。SetMaxLength(真的,0 x100000);
dicomAssociateRequest。AddPresentation(1,0, UID_VERIFICATION_CLASS);
dicomAssociateRequest。UID_IMPLICIT_VR_LITTLE_ENDIAN AddTransfer(1日);
dicomAssociateRequest。AddPresentation(3,0, pszStorageClass);
dicomAssociateRequest。UID_IMPLICIT_VR_LITTLE_ENDIAN AddTransfer (3);
//发送A-Associate-RQ消息
LogMessage(文本(“CMyClient:: SendAssociateRequest”));
nRet = client.SendAssociateRequest(&dicomAssociateRequest);
如果(! client.Wait (5000))
{
LogMessage(文本(“超时:客户端。连接”));
nRet = DICOM_ERROR_NET_TIME_OUT;
转到清理;
}
}
如果(nRet == DICOM_SUCCESS)
{
L_UCHAR nPresentationID = client.GetAssociate()->FindAbstract(pszStorageClass);
L_UINT16 uUniqueID = 99;
LogMessage(文本(“CMyClient:: SendCStoreRequest”));
客户端。发送CStoreRequest(nPresentationID, uUniqueID, pszStorageClass, pszStorageInstance, COMMAND_PRIORITY_MEDIUM, TEXT(“没有”), 1, &ds);
WaitForProcessing ();
}
LogMessage(文本(“CMyClient:: SendReleaseRequest”));
client.SendReleaseRequest ();
WaitForProcessing ();
清理:
LogMessage(文本(“CMyClient:接近”));
client.Close ();
client.Wait (1000);
LogMessage(文本(“\ tCMyServer:接近”));
server.Close ();
LDicomNet:关闭();
返回nRet;
}
}