【转】03.Dicom 学习笔记-DICOM C-Get 消息服务
轉(zhuǎn)自:https://www.jianshu.com/p/c7f5b9fa597c
引言
??前篇介紹了 DICOM C-Find 消息服務(wù),本文結(jié)合開源 DICOM 庫 fo-dicom 詳細介紹一下 C-Get 服務(wù)。
?
C-Get 消息服務(wù)
??C-Get 服務(wù)主要用于獲取影像,用于一個 DIMSE-service-user 在同等的DIMSE-service-user 上查詢復(fù)合 SOP 實例的屬性滿足查詢條件給出的一組屬性的復(fù)合 SOP 實例,并取回這些符合條件的復(fù)合 SOP 實例,同時在這個過程中將觸發(fā)一個或多個 C-STORE 子操作過程,所有的操作(包含 C-STORE 子操作)均在同一個 association 連接中。
??有關(guān)C-Get 服務(wù)流程圖,我通過不同的 C-Get SCP 的實現(xiàn),出現(xiàn)了兩種流程圖,參考如下:
- 每個 C-Store 子操作完成后都會有一個 C-Get 響應(yīng)
?
C-Get workflow 1
-C-Get 響應(yīng)只會在 C-Store 子操作全部完成后發(fā)送
?
C-Get workflow 2
?
C-Get SCU
??通過結(jié)合 DICOM 開源庫 fo-dicom 來實現(xiàn) C-Get SCU,部分代碼如下:
需要引用命名空間【Dicom.Network】和【System.Threading】
?
using Dicom.Network; using System.Threading;?
var client = new DicomClient();// 添加能夠接收的抽象語法 abstract syntax,通過查看 DICOM 文件的 SOPClassUID 可獲得,否則不會觸發(fā) C-Store 子操作 var pc = DicomPresentationContext.GetScpRolePresentationContext(DicomUID.CTImageStorage); client.AdditionalPresentationContexts.Add(pc);var counter = 0; var locker = new object(); client.OnCStoreRequest = (DicomCStoreRequest request) => {lock (locker){++counter;Console.WriteLine(DateTime.Now.ToString() + " recived, count is " + counter);}// 可以通過 request.Dataset 獲取到 DICOM 文件return new DicomCStoreResponse(request, DicomStatus.Success); };var get = new DicomCGetRequest({StudyInstanceUID});var handle = new ManualResetEventSlim(); get.OnResponseReceived = (DicomCGetRequest requ, DicomCGetResponse response) => {if (response.Remaining == 0){handle.Set();} }; client.AddRequest(get); client.Send({C-Get SCP IP}, {C-Get SCP Port}, false, {C-Get SCU AE Title}, {C-Get SCP AE Title}); handle.Wait();- StudyInstanceUID:檢查唯一標識;
- C-Get SCP IP:C-Get 服務(wù)端的 IP 地址或機器名;
- C-Get SCP Port:C-Get 服務(wù)端的端口;
- C-Get SCU AE Title:C-Get 客戶端應(yīng)用實體的名稱;
- C-Get SCP AE Title:C-Get 服務(wù)端應(yīng)用實體的名稱;
C-Get SCP
??在本文開頭部分給出了兩張流程圖,這是通過不同 C-Get SCP 的實現(xiàn)進行抓包得到的,針對這塊流程中不同的地方在 DICOM 標準中到底是如何定義的,可以在 DICOM 標準的第4部分【C.1.4 Service Definition】 中找到,具體的描述如下:
A C-GET service conveys the following semantics:
?
The SCU supplies Unique Key values to identify an entity at the level of the retrieval. The SCP generates C-STORE sub-oper- ations for the corresponding storage SOP Instances identified by the Unique Key values. These C-STORE sub-operations occur on the same Association as the C-GET service and the SCU/SCP roles will be reversed for the C-STORE.
?
The SCP may optionally generate responses to the C-GET with status equal to Pending during the processing of the C-STORE sub-operations. These C-GET responses indicate the number of Remaining C-STORE sub-operations and the number of C- STORE sub-operations returning the status of Success, Warning, and Failed.
?
When the number of Remaining C-STORE sub-operations reaches zero, the SCP generates a final response with a status equal to Success, Warning, Failed, or Refused. This response may indicate the number of C-STORE sub-operations returning the status of Success, Warning, and Failed. If the status of a C-STORE sub-operation was Failed a UID List will be returned.
?
The SCU may cancel the C-GET service by issuing a C-GET-CANCEL request at any time during the processing of the C- GET. The SCP terminates all incomplete C-STORE sub-operations and returns a status of Canceled.
這里已經(jīng)說明了是可選的,更詳細的 C-Get 過程在 DICOM 標準第7部分【9.1.3.2】有描述,不過針對這塊沒有描述,所以才出現(xiàn)如文章開頭兩種流程圖。C-Get SCP 可以通過派生 DicomService 服務(wù)類來實現(xiàn) Dicom 服務(wù)的基本框架,然后實現(xiàn) IDicomServiceProvider 和 IDicomCGetProvider 接口來實現(xiàn),部分代碼可以參考這里,核心部分是實現(xiàn) OnCGetRequest 方法。
?
C-Get 過程分析
??我這里選擇本文開頭第一種流程圖的抓包數(shù)據(jù)進行分析,由于包的數(shù)據(jù)量比較大,我這里過濾掉不能被解碼成 DICOM 協(xié)議的包,只分析能被解碼成 DICOM 協(xié)議的包,先看前面部分:
?
C-Get pcap
紅色框內(nèi)的兩行是兩個 AE 建立 association 的過程:
接著藍色框第一行就是 C-Get SCU(10.3.13.202)向 C-Get SCP(10.3.2.209) 發(fā)送 C-Get 請求了;
藍色框第二行是 C-Get SCP(10.3.2.209)經(jīng)過查找,找到滿足條件的復(fù)合 SOP 實例對象,返回找到的信息,從下圖紅色框可以看到有3個子操作待執(zhí)行,這里表示找到了3個滿足條件的復(fù)合 SOP 實例對象,接下來會觸發(fā)3個 C-Store 子操作。
?
C-Get Response
接著就是 C-Store 歸檔數(shù)據(jù)的操作了
C-Store
一個復(fù)合 SOP 實例對象數(shù)據(jù)歸檔的最后一個包是一個畸形數(shù)據(jù)包【Malformed packet】:
Malformed packet
從上圖可以看出,前面?zhèn)鬏數(shù)臄?shù)據(jù)包都將在收到 Frame 609后進行重組,Frame 609就在 Malformed Packet 這個數(shù)據(jù)包,下面的藍色框是這個數(shù)據(jù)包將前面所有收到的數(shù)據(jù)包重組之后,解析 SOP 對象得到的 TAG 值;
然后 C-Get SCU(10.3.13.202)向 C-Get SCP(10.3.2.209) 發(fā)送 C-Store 響應(yīng),并告知狀態(tài)為 Success;
C-Store Response
接著 C-Get SCP(10.3.2.209)向 C-Get SCU(10.3.13.202)發(fā)送 C-Get 請求的響應(yīng),內(nèi)容包括當前的狀態(tài)、剩下多少個子操作待執(zhí)行、已完成多少個子操作和失敗的子操作個數(shù):
C-Get Response
這個數(shù)據(jù)包結(jié)束后就又是下一個 SOP 實例對象的歸檔數(shù)據(jù)包了,和上面一樣,這里不再繼續(xù)分析。
當所有的 C-Store 子操作結(jié)束后 C-Get SCP(10.3.2.209)會向 C-Get SCU(10.3.13.202)發(fā)送一個 C-Get 請求的響應(yīng),這里會返回 C-Get 請求的狀態(tài),如果前面的子操作都成功的話,這里會返回狀態(tài)為 Success:
C-Get Response
最后 C-Get SCU(10.3.13.202)向 C-Get SCP(10.3.2.209) 發(fā)送 A-RELEASE 請求斷開 association;
C-Get SCP(10.3.2.209)響應(yīng) C-Get SCU(10.3.13.202)的 A-RELEASE 請求,然后斷開兩個 AE 之間的 association;
至此,整個 DICOM 協(xié)議相關(guān)的包就全部發(fā)送完畢。
作者:Statmoon
鏈接:https://www.jianshu.com/p/c7f5b9fa597c
來源:簡書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
總結(jié)
以上是生活随笔為你收集整理的【转】03.Dicom 学习笔记-DICOM C-Get 消息服务的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 直播时饲养员用膝盖暴击猩猩脸部 哀嚎着逃
- 下一篇: 【转】VTK修炼之道1_初识VTK