標籤:dcmtk dicom mdcm worklist fo-dicom
背景:
最近在做關於PACS終端與RIS系統之間進行worklist查詢的相關調試工作,因此又重新對DICOM3.0標準中關於網路傳輸的部分進行了閱讀,在此將本周的工作進行一下總結,以加深對DICOM3.0標準的認識,從底層更加清晰的瞭解worklist查詢、C-STORE、C-FIND等各種服務。
要點:1)名詞簡稱
該部分中會出現很多的常見名詞的縮寫,因此為了更好的理解其含義,先給出各個名詞所對應的全稱,這裡沒有用中文進行翻譯原因有二,其一是因為英文很簡單,而且表意很清楚,其二是因為目前DICOM3.0標準還沒有官方的中文版,所以我也不敢造次進行翻譯。
常見的簡稱及其全稱如下:
ACSE:Association Control Service Element
AE:Application Entity
CMIS:Common Management Information Service
CMISE:Common Management Information Serivce Element
DICOM:Digital Imaging and Communications in Medicine
DIMSE:DICOM Messsage Service Element
DIMSE-C:DICOM Message Service Element-Composite
DIMSE-N:DICOM Message Service Element-Normalized
HL7:Health Level 7
OSI:Open Systems Interconnection
PDU:Protocol Data Unit
PDV:Protocol Data Value
SOP:Service Object Pair
TCP/IP:Transmission Control Protocol/Internet Protocol
DUL:Dicom Upper Layers
2)DICOM網路通訊模型
DICOM網路服務是建立在傳統OSI七層模型之上的端到端的通訊服務,包括服務端和用戶端。其基本的通訊服務模型如所示:
與傳統的OSI七層模型對比一下,可以看出DICOM3.0標準中所描述的DICOM網路通訊服務所包含的並非是OSI七層中簡單的某一層,而是對從傳輸層/網路層向上的各層都分別進行了詳細的描述和定義。下一節我會針對DICOM3.0標準的幾個部分分別來詳細介紹一下DICOM網路通訊服務的各個層,或者說各個模組。
3)DICOM3.0標準對DICOM網路通訊的描述
下面直接給出DICOM3.0標準中的幾個附圖,首先從整體上對DICOM3.0標準有一個把握,如下所示:
從右圖可以看出DICOM通訊模型是建立在TCP/IP層之上的,最底層的是DICOM Upper Layer Protocol,該部分主要負責與TCP相對接,在此之上就是DICOM3.0標準給出的DICOM通訊模型,與上一節中的OSI七層模型相比可知,DICOM通訊模型涵蓋了會話層(Session)、展示層(Presentation)和應用程式層(Application)。會話層(Session)主要負責為通訊雙方制定通訊方式,並建立、登出會話。該部分對應的是DICOM3.0標準中的第8部分,即ACSE(Association Control Service Element);展示層(Presentation)能為不同的用戶端提供資料和資訊的文法轉換內碼,使系統能解讀成正確的資料。同時,也能提供壓縮解壓、加密解密。與之相對應的是DIMSE服務,即DICOM3.0標準的第7部分,該部分給出了眾多服務(C-STORE、C-FIND、C-GET、C-MOVE、C-ECHO)的編碼格式。
左圖是右圖中DICOM Upper Layer Service以上服務內部結構的細化,從中也可以看出與之相對應的DICOM3.0的各個部分。下面給出一個更全面的結構:
中在簡單的對DICOM3.0標準中的進行組合後,也給出了DCMTK源碼庫中與各個層相對應模組的名稱,從名稱簡寫上也可以看出整個DICOM網路通訊是如何完成的。其中與DICOM通訊服務相關的幾個檔案有dimse.h、assoc.h、dul.h(順序按照OSI七層模型從上到下),其中dimse.h檔案中給出了DIMSE層的各種資訊的結構體(如T_DIMSE_Message、T_DIMSE_C_EchoRQ、T_DIMSE_C_EchoRSP等)以及各種服務的函數(如DIMSE_echoUser、DIMSE_sendEchoResponse、DIMSE_storeUser、DIMSE_storeProvider等)。dimse.h檔案中定義的各類服務函數,都會有一個關於網路連接的參數T_ASC_Association *assoc,如:
從參數類型就可以猜出該類型定義在assoc.h檔案中(如),assoc.h檔案的備忘指出該檔案為DICOM網路應用提供了串連管理(association management),檔案中定義的所有結構都是為了支援串連建立的(如表示上下文、抽象語義、傳輸語義、最大PDU長度等等)。同時檔案中也指出了其中的函數利用的是DICOM Upper Layer的服務來實現的。而T_ASC_Association結構就代表一次活動連結。
既然assoc.h標頭檔已經指明了該模組是在Dicom Upper Layer基礎上實現的,因此可以猜到連結的各類函數的原始碼實現中必定調用了dul.h檔案中的函數,此處已ASC_initializeNetwork函數為例,如所示,該函數內部直接調用了DUL_InitializeNetwork函數,想必如果按照上面我們的分析,繼續追蹤下去的話,一定就會出現TCP層的函數,即我們常用的通訊端socket函數(如果讀者喜歡可自行查看dul.h中函數的原始碼,例如DUL_initializeNetwork函數中通過initializeNetworkTCP函數直接使用了socket的常見操作函數,如socket建立通訊端函數、setsockopt設定通訊端函數、bind綁定通訊端函數 等等)
至此通過查看DCMTK開源庫源碼,使得我們對上面的整體結構圖有了更直觀的認識,從而對DICOM3.0標準也有了更好的瞭解。
實際工程測試:
在查看完DCMTK源碼設計後,為了更真實的感受和掌握DICOM網路通訊的過程,此處以常見的PACS與RIS系統之間的worklist查詢服務和DICOM的C-STORE映像儲存服務為例,對服務端與用戶端通訊的真實資料包進行抓取分析,從而更好、更直觀的認識DICOM通訊服務。
1)測試載入器:
為了模擬DICOM的通訊模型,自然需要構造服務和客戶兩端,DCMTK開源庫的bin中給我們提供了很好的工具。此處選用的工具分兩類
服務端 |
用戶端 |
wlmscpfs.exe |
findscu.exe |
storescp.exe |
storescu.exe |
另外為了與DICOM3.0中對DICOM網路服務的各種結構(如DIMSE、PDU)和指令(A-ASSOCIATION、C-FIND)的詳細介紹進行對比,將本地類比的服務端與用戶端的通訊資料包進行了抓取,利用的本地迴路抓包工具室RawCap.exe,將抓取的資料包存成pcap檔案,然後利用Wireshark工具強大的統計分析功能進行直觀的對比分析。
本地迴路抓包工具 |
RawCap.exe |
資料包分析查看工具 |
Wireshark |
2)worklist查詢服務的通訊過程分析
第一步,啟動本地迴路抓包工具,RawCap.exe 5 dumpfile.pcap(可以利用RawCap.exe -h來查看RawCap.exe工具的使用)
第二步,啟動worklist服務端程式,wlmscpfs.exe –d 104 –dfp wlistdb >worklist-server.txt(利用shell的重新導向將調試資訊儲存到worklist-server.txt中)
第三步,啟動workist查詢用戶端程式,findscu.exe –d 127.0.0.1 104 testqry.wl –aec OFFIS >worklist-client.txt(testqry.wl檔案是上一篇博文http://blog.csdn.net/zssureqh/article/details/38775315中測試使用的,其中設定了PatientID=123456)
然後等待整個通訊過程截止,RawCap.exe會得到一個名為dumpfile.pcap的資料包檔案,另外也會得到服務端和用戶端的兩個調試資訊文字檔,分別是worklist-server.txt和worklist-client.txt。
注意:有些時候利用重新導向將調試資訊輸出到文字檔會發生中斷錯誤,因此也可以直接將結果顯示到console視窗,然後將其手動拷貝儲存到相應的檔案中。我在原生操作如所示:
至此整個資料抓取和資訊記錄的任務就完成了,接下來就是我們的分析階段了。
首先直接使用文字編輯器開啟兩個調試資訊文字檔,我在本地的結果如所示:
調試資訊中也基本給出了我們想要的資料,例如A-ASSOCIATE-AC、A-ASSOCIATE-RQ、DIMSE MESSAGE等。中的邊緣附件的黃色箭頭示意的是兩端(即兩個DICOM AE)進行真實交流時資料流流過的各層的順序,這與OSI中的類似。途中紅色矩形框表示的1、2、3、4等是DICOM協議層(association)的互動順序,從資料中可以看出association層對一些底層結構(如PDU、PDV)進行了約定;藍色框標示的是DIMSE協議層,該層主要定義的是DICOM的各種服務,如C-STORE、C-FIND等。
然後,我們利用Wireshark工具開啟dumpfile.pcap資料包檔案。
利用Protocol的篩選,我們只觀察DICOM協議的相關資料包(有興趣的可以將整個過程的所有資料包分析一下)。如所示,可以清晰的看到findscu用戶端與worklist服務端的互動過程。雙擊其中的第一條互動資訊,如所示:
此圖中可以清晰的看到完整的association層的資料包,總紅色圓圈所示,01類型代表的正是ASSOCIATE-RQ PDU 類型,而隨後緊跟著的就是DICOM3.0第8部分Table 9-11中約定的各個欄位。
3)C-STORE服務提供者(SCP)、使用者(SCU)通訊過程分析
該部分的測試流程與2)中worklist查詢的測試流程是相同的。
第一步,啟動本地迴路抓包工具,RawCap.exe 5 dumpfile.pcap(可以利用RawCap.exe -h來查看RawCap.exe工具的使用)
第二步,啟動storescp服務端程式,storescp.exe -d 104 -aet OFFIS >storescp.txt(利用shell的重新導向將調試資訊儲存到storescp.txt中)
第三步,啟動storescu請求用戶端程式,storescu.exe –d 127.0.0.1 104 –f test.dcm –aec OFFIS >storescu.txt(test.dcm是一個標準的dcm檔案)
然後等待整個通訊過程截止,RawCap.exe會得到一個名為dumpfile.pcap的資料包檔案,另外也會得到服務端和用戶端的兩個調試資訊文字檔,分別是storescp.txt和storescu.txt。
分析過程也與2)中相同,此處就不細說了,只給出結果圖。
【備忘】:
正是利用上述工具,解決了上一篇博文利用fo-dicom發送C-Find查詢Worklist失敗的問題。具體的排查過程就是先利用DCMTK開源工具包進行類比,然後利用工具抓取資料包分析結果,在確定無誤的情況下,轉而轉到fo-dicom環境下,同樣抓取資料包分析錯誤原因。然後單步調試到fo-dicom開源庫的C-FInd發起函數CreateWorklistQuery中,確定了問題出現的原因。具體的連結可以參見我的Github:https://github.com/zssure-thu/fo-dicom。該分支中我暫時記錄了此次修改的代碼,等待後續進一步確認。
博文中的具體檔案已經上傳到CSDN,連結為:http://download.csdn.net/detail/zssureqh/7870789
[email protected]
時間:2014-09-06 0:55
DICOM醫學影像處理:全面分析DICOM3.0標準中的通訊服務模組