国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

dicom網(wǎng)絡(luò)通訊入門(2)

2019-11-17 03:14:55
字體:
供稿:網(wǎng)友

dicom網(wǎng)絡(luò)通訊入門(2)

第二篇,前面都是閑扯 其實(shí)正文現(xiàn)在才開始,這次是把壓箱底的東西都拿出來了。首先我們今天要干的事是實(shí)現(xiàn)一個(gè)echo響應(yīng)測(cè)試工具 也就是echo 的scu,不是實(shí)現(xiàn)打印作業(yè)管理么。同學(xué)我告訴你還早著呢。本來標(biāo)題取的就是《dicomviewer 第二彈 之 實(shí)現(xiàn)打印管理》名字多霸氣,最后我又改回來了。首先你得把數(shù)據(jù)組織方式搞懂 那就是pdu 和dimse 元素 數(shù)據(jù)元素。然后基于這之上你得把協(xié)商連接這塊搞懂 ,協(xié)商連接都沒通過不用說后面的了。然后你得把實(shí)現(xiàn)一個(gè)功能 比如打印 ,scu跟scp之間你來我往的 過程和概念搞懂 也就是dimse 然后才是服務(wù)類。最夠你全都理解了 并且寫出東西來了能跟醫(yī)院的設(shè)備正常 連接和操作了,那么恭喜你 差不多了。

最后要說的是: 解析dicom文件那篇你們都已經(jīng)看過了,dicom網(wǎng)絡(luò)通訊跟解析文件是一樣的 只不過解析的是socket數(shù)據(jù)流里的 元素 數(shù)據(jù)結(jié)構(gòu)本身是一樣的,然后他有一些規(guī)范和標(biāo)準(zhǔn) ,這就是dimse 和服務(wù)類 這些好像都在dicom標(biāo)準(zhǔn)的第四章 第八章 第七章 。

實(shí)現(xiàn)這一大坨的東西 有點(diǎn)望而卻步了吧,其實(shí)總結(jié)起來就一句話 概括 按照dicom標(biāo)準(zhǔn) 封裝數(shù)據(jù) 處理數(shù)據(jù) ,然后根據(jù)特殊的參數(shù)和應(yīng)用場(chǎng)景 依規(guī)范響應(yīng)數(shù)據(jù),。好廢話少說,開工 看過 標(biāo)準(zhǔn)簡(jiǎn)介那篇博客 的都知道:PDU是一種數(shù)據(jù)結(jié)構(gòu) dataElement是一種數(shù)據(jù)結(jié)構(gòu)pdu結(jié)構(gòu)總共7種 其中用于連接控制的就占了6種 A-Associate—RQ PDU連接請(qǐng)求協(xié)議數(shù)據(jù)單元,用于關(guān)聯(lián)請(qǐng)求。A-Associate.AC PDU基于DICOM標(biāo)準(zhǔn)的醫(yī)學(xué)圖像通信過程的實(shí)現(xiàn)連接接受協(xié)議數(shù)據(jù)單元,A.Associate—RJ PDU連接拒絕協(xié)議數(shù)據(jù)單元,A-Release-RQ PDU用于對(duì)關(guān)聯(lián)請(qǐng)求的應(yīng)答。用于拒絕關(guān)聯(lián)請(qǐng)求。連接釋放請(qǐng)求協(xié)議數(shù)據(jù)單元,A-Release.RSP PDU連接釋放響應(yīng)協(xié)議數(shù)據(jù)單元,A.Abort PDU傳輸內(nèi)容的pdu只有一種P.DATA.TF PDU,當(dāng)通訊雙方建立了關(guān)聯(lián)之后,就可以使用P.DATA-TF所提供的傳輸服務(wù)來實(shí)現(xiàn)不同的通信功能了。總之你在進(jìn)行后面的dimse發(fā)送之前先得建立連接,否則你什么也搞不了。好下面就協(xié)商連接的pdu進(jìn)行分析:

你問這圖是怎么來的 dicom 第八章 31頁(yè)。是不是跟上面說的是一樣的 開始兩字節(jié) 然后4字節(jié)表示長(zhǎng)度,只不過這個(gè)更詳細(xì)了。協(xié)商連接pdu說起有6種 其實(shí)有好多是大同小異 比如Associate pdu, 他分rq 和ac rq是請(qǐng)求 ac是響應(yīng)。我把協(xié)商連接概述一下

概述之前,什么是通訊:還是炒剩飯 我又得把以前說過的話像背書一樣的背一遍了 其實(shí)他確實(shí)是那么回事。什么是通訊 :命令tag +數(shù)據(jù)tag 一起組成sop ,就好象說一句這樣的話:“把這根蘿卜拿去給我切了” “喏 ,蘿卜” 。其實(shí)這就是通訊 跟人與人之間傳達(dá)意思一樣。說話的時(shí)候太熟練了 沒察覺到 你要仔細(xì)去想 你自己是一臺(tái)電腦 ,會(huì)是一個(gè)什么樣的步驟。網(wǎng)絡(luò)傳輸 跟文件組織 是一樣的格式 。不過有命令tag 。很多命令tag組合到一堆這稱之為dimse。 echo n-create c-find c-store 這些都稱之為dimse ,記住沒有c-PRint 大哥打印管理是由很多組dimse 包括n-create 那些 你來我往的一套組成 比如 先n-create 什么東西 再 n-set什么東西,他有一種邏輯規(guī)范 什么參數(shù)錯(cuò)誤則不進(jìn)行n-set。這很多組dimse稱之為服務(wù)類 ,比如打印管理 就是一個(gè)服務(wù)類。這些規(guī)范在dicom標(biāo)準(zhǔn)的第八章有說明。總之在dimse傳遞之前 你必須得協(xié)商連接。dicom標(biāo)準(zhǔn)的地址是這個(gè)http://medical.nema.org/standard.html,英文的 。看也比較困難 裝裝面子,主要是理解就行了 我看的也是別人翻譯的中文的。不過官方的就是官方的 沒辦法 某些地方你找不到原因 想?yún)⒄兆顦?biāo)準(zhǔn)的指示 你還是得硬著頭皮去看英文文檔。Associate pdu 協(xié)商連接的過程:又說多了 不論如何在進(jìn)行dimse之前必須得進(jìn)行連接協(xié)商 因?yàn)槟闩c別人進(jìn)行通訊首先你得確定幾個(gè)東西。 ,談話的主題是什么,你是用哪國(guó)語言。這兩個(gè)東西一個(gè)稱之為虛擬語法 abssyntax 一個(gè)稱之為傳輸語法 transfersyntax 傳輸語法其實(shí)主要確定兩個(gè)東西 字節(jié)序 和 vr表示方式 ,如果你不知道字節(jié)序是什么 請(qǐng)自己百度 vr表示方式 跟文件解析一樣的,他們兩個(gè)一起被稱之為表達(dá)上下文。注意表達(dá)上下文有多個(gè) 每個(gè)都有id。如果你是scp端 那么連接協(xié)商響應(yīng) 也就是association-ac的時(shí)候你要告知 以你scp程序的服務(wù)能力可以完成哪些表達(dá)上下文的服務(wù) 傳輸語法語法是什么,如果服務(wù)不了也要給出對(duì)應(yīng)的上下文id 并進(jìn)行告知。這樣的話scu端知道你服務(wù)不了就知難而退 主動(dòng)斷開連接。 其次還有些其他東西比如pdu最大數(shù)據(jù)長(zhǎng)度 一般是0x4000。好了講完了 這就是協(xié)商連接的過程 對(duì)照上面的圖理解了否。這是官方的解釋:

官方的解釋 網(wǎng)絡(luò)協(xié)議是分層的,Dicom ul p ,稱之為dicom上層協(xié)議。 也就是上圖的dicom ul service provider。 反正要按照osi的標(biāo)準(zhǔn)來, 也就是說要定義一個(gè)associate-rq 或者 ac的數(shù)據(jù)結(jié)構(gòu)來,一切的數(shù)據(jù)序列化或者反序列化都由 dicom ul service provider 來進(jìn)行,反正只怕忽悠不死你。反正他說是那樣說 我們自己按照自己的方式來。好終于要?jiǎng)哟a了 ,我喜歡的事情來了 噢啦啦啦。其實(shí)這是一個(gè)抽象化的過程,把你的想法付諸行動(dòng) 代碼化.就像某人說過的 主要的不是技術(shù) 而是思路。分成兩步 根據(jù)文檔定義 associate Pdu的數(shù)據(jù)結(jié)構(gòu),遵循上面說的原則 一個(gè)associate pdu有多高 pst Item,我們把pst Item定義為子項(xiàng),然后serial()是associate pdu的網(wǎng)絡(luò)序列化函數(shù):

  1 public enum PDUTypes  2     {  3         AssociateRQ = 0x01,  4         AssociateAC = 0x02,  5         AssociateRJ = 0x03,  6         DataTransfer = 0x04,  7         AssociateReleaseRQ = 0x05,  8         AssociateReleaseRP = 0x06,  9         AssociateAbort = 0x07, 10  11         applicationContext = 0x10, 12         PresentationContext = 0x20, 13         UserInformation = 0x50, 14     } 15  16     struct PDUAssociate { 17         //header 18         public byte pduType; 19         public uint length; 20         public ushort ProteocalVersion; 21         public string CallEdAE ;//length=16 22         public string CallingAE ; 23  24         //10 25         public byte aPPType; 26         public ushort appLength; 27         public string appName; 28  29         //20 30         public IList<PstItem> pstItems; 31         //50 userinfo 32         public byte userinfoType; 33         public ushort userinfoLength; 34         public byte maxnumType; 35         public ushort maxnumLength; 36         public uint maxnum;//DATA-TF PDU的可變字段的最大長(zhǎng)度 一般為0x400 即1024 37         public byte impType;//關(guān)于實(shí)現(xiàn)類的 38         public ushort impLength; 39         public string impUID; 40         public byte impVersionType; 41         public ushort impVersionLength; 42         public string impVersion; 43  44         public byte[] serial() 45         { 46             if (length == 0) 47                 return null; 48             MemoryStream _stream = new MemoryStream((int)length + 6); 49             WarpedStream stream = new WarpedStream(_stream); 50             #region 序列化aassociateAC PDU 51             //header 52             stream.writeByte(pduType); 53             stream.skip_write(1); 54             stream.writeUint(length);//最低要94 我去 這是為什么呢 55             stream.writeUshort(ProteocalVersion); 56             stream.skip_write(2); 57             stream.writeString(CallEdAE, 16); 58             stream.writeString(CallingAE, 16); 59             stream.skip_write(32); 60  61             //10 62             stream.writeByte(appType); 63             stream.skip_write(1); 64             stream.writeUshort(appLength); 65             stream.writeString(appName, 0); 66             //21 67  68             for (int i = 0; i < pstItems.Count; i++) 69             { 70                 if (pstItems[i].used) 71                 { 72                     stream.writeByte(pstItems[i].pstType); 73                     stream.skip_write(1); 74                     stream.writeUshort(pstItems[i].pstLength); 75                     stream.writeByte(pstItems[i].pstID); 76                     stream.skip_write(3); 77                     //if (pstItems[i].used) 78                         //stream.writeBytes(new byte[] { 0x00, 0x00, 0x00 }); 79                     //else 80                     //30 81                     if (pstItems[i].pstType == 0x20)//如果是20則為printSCU 82                     { 83                         stream.writeByte(pstItems[i].absType); 84                         stream.skip_write(1); 85                         stream.writeUshort(pstItems[i].absLength); 86                         stream.writeString(pstItems[i].absStr, 0); 87                     } 88  89                     stream.writeByte(pstItems[i].tsfType); 90                     stream.skip_write(1); 91                     if (pstItems[i].used) 92                         stream.writeUshort(pstItems[i].tsfLeghth); 93                     else 94                         stream.writeUshort(0); 95                     if (pstItems[i].used) 96                         stream.writeString(pstItems[i].tsfStr, 0); 97                 } 98                 else 99                 {100                     stream.writeByte(pstItems[i].pstType);101                     stream.skip_write(1);102                     stream.writeUshort(0x08);103                     stream.writeByte(pstItems[i].pstID);104                     stream.writeBytes(new byte[] { 0x00, 0x04, 0x00 });105                     stream.writeBytes(new byte[] { 0x40, 0x00, 0x00, 0x00 });106                 }107             }108             109 110             //50111             stream.writeByte(userinfoType);112             stream.skip_write(1);113             stream.writeUshort(userinfoLength);114 115             stream.writeByte(maxnumType);116             stream.skip_write(1);117             stream.writeUshort(maxnumLength);118             stream.writeUint(maxnum);119 120             stream.writeByte(impType);121             stream.skip_write(1);122             stream.writeUshort(impLength);123             stream.writeString(impUID, 0);124 125             stream.writeByte(impVersionType);126             stream.skip_write(1);127             stream.writeUshort(impVersionLength);128             stream.writeString(impVersion, 0);129             #endregion130 131             _stream.Flush();132             byte[] data = _stream.GetBuffer();133             stream.close();134             _stream.Close();135             return data;136         }137     }138 139     struct PstItem140     {141         //20 abstractsyntax transfersyntax傳輸語法 142         public byte pstType;143         public ushort pstLength;144         public byte pstID;145         public bool used;146         //public byte pstRec; //保留字節(jié) 有效項(xiàng)是00 00 00 無效項(xiàng)是00 04 00147         public byte absType;//20的子項(xiàng) 30 40 讀取的時(shí)候應(yīng)該跟20一并讀出來148         public ushort absLength;149
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 雅江县| 芜湖市| 招远市| 江川县| 宜良县| 墨玉县| 成都市| 饶阳县| 玉门市| 北碚区| 通河县| 天等县| 梅河口市| 阿克陶县| 乐安县| 蚌埠市| 迭部县| 墨脱县| 西峡县| 垦利县| 焦作市| 道真| 桂平市| 浦东新区| 错那县| 宿松县| 合江县| 湖北省| 瑞丽市| 遂昌县| 城口县| 婺源县| 崇礼县| 海城市| 集贤县| 绥德县| 镇安县| 若羌县| 柳河县| 西峡县| 东台市|