public override PDU AETitle(PDU pdu) { AETsBtoS(pdu); if (uced == pced && ucing == pcing) { /*构造回复AC * 1实例化新的AC类(保存配置信息) * 2调用AC write,传入相应参数ACpdu,返回ACpdu * 3调用AC.r * */ AAssociateAC ACpdu = new AAssociateAC(); ACpdu.uCalledAET = pdu.uCalledAET; ACpdu.uCallingAET = pdu.uCallingAET; ACpdu.VItems = pdu.VItems; ACpdu = ACpdu.writeAC(ACpdu); pdu.r = ACpdu.r; pdu.log = "DICOMSCU << A - ASSOCIATE - AC PDU" + "\r\n"; } else if (uced != pced) { pdu.r = HexStringToByteArray("03 00 0000000A 00 02 03 07"); pdu.log = "DICOMSCU << A - ASSOCIATE - RJ PDU" + "\r\n"; } else if (ucing != pcing) { pdu.r = HexStringToByteArray("03 00 0000000A 00 02 03 03"); pdu.log = "DICOMSCU << A - ASSOCIATE - RJ PDU" + "\r\n"; } return(pdu); }
//构造AC public AAssociateAC writeAC(AAssociateAC ACpdu) { //构造AC头部 //type ACpdu.PDUType = HexStringToByteArray("02"); // reserve1 byte[] reser1 = Vreserve(1); //unkonw length //version ACpdu.ProtocalVersion = HexStringToByteArray("0001"); //reserve2 byte[] reser2 = Vreserve(2); //called ACpdu.uCalledAET //calling ACpdu.uCalledAET //reserve32 byte[] reser32 = Vreserve(32); //构造context ACpdu = writeAPP(ACpdu); ACpdu = writeAPer(ACpdu); ACpdu = writeUInfo(ACpdu); ACpdu.Context = new Byte[ACpdu.App.Length + ACpdu.Per.Length + ACpdu.UInfo.Length]; Array.Copy(ACpdu.App, 0, ACpdu.Context, 0, ACpdu.App.Length); Array.Copy(ACpdu.Per, 0, ACpdu.Context, ACpdu.App.Length, ACpdu.Per.Length); Array.Copy(ACpdu.UInfo, 0, ACpdu.Context, ACpdu.App.Length + ACpdu.Per.Length, ACpdu.UInfo.Length); //获取长度,固定头部长度+上下文长度 ACpdu.PDULength = (uint)(68 + ACpdu.Context.Length); //uint转换为byte数组,格式控制4byte byte[] pdul = BitConverter.GetBytes(ACpdu.PDULength); Array.Reverse(pdul); ACpdu.r = new Byte[ACpdu.PDULength + 6]; //排序AC内容,存入r int len = 0; Array.Copy(ACpdu.PDUType, 0, r, len, ACpdu.PDUType.Length); len += ACpdu.PDUType.Length; //type Array.Copy(reser1, 0, r, len, 1); len += 1; //re1 Array.Copy(pdul, 0, r, len, pdul.Length); len += pdul.Length; //length Array.Copy(ACpdu.ProtocalVersion, 0, r, len, ACpdu.ProtocalVersion.Length); len += ACpdu.ProtocalVersion.Length; //version Array.Copy(reser2, 0, r, len, 2); len += 2; //re2 Array.Copy(ACpdu.uCalledAET, 0, r, len, ACpdu.uCalledAET.Length); len += 16; //ced Array.Copy(ACpdu.uCallingAET, 0, r, len, ACpdu.uCallingAET.Length); len += 16; //cing Array.Copy(reser32, 0, r, len, 32); len += 32; //re32 Array.Copy(ACpdu.Context, 0, r, len, ACpdu.Context.Length); len += ACpdu.Context.Length; //contex return(ACpdu); }
public AAssociateAC writeAPer(AAssociateAC ACpdu) { /*根据RQ编写, * 1 遍历VItems取type=20,30,第一个40的item * 2 复制20,40的内容,注意 AC20length=RQ20length-(RQ30length+4) */ foreach (Item i in ACpdu.VItems) { if (i.ItemType == "20") { per += ("21" + "00"); length20 = i.ItemLength; PCID20 = i.PCID; } if (i.ItemType == "30") { //AC20length=RQ20length-(RQ30length+4) length20 -= (i.ItemLength + 4); per += "00"; per += Convert.ToString(length20, 16); per += (PCID20 + "000000"); } if (i.ItemType == "40") { per += (i.ItemType + "00"); per += "00"; per += Convert.ToString(i.ItemLength, 16); per += converuid(i.Uid); } } per = per.Replace(".", "2E"); if (per.Length % 2 != 0) { per += "0"; } ACpdu.Per = HexStringToByteArray(per); return(ACpdu); }
//处理接收的客户端数据 public void ReceiveFromClient() { /* * 1 循环读取:先读取一位,判断类型,使用不同方法解码(RQ/AC 和 RJ/RL) * 2 安位循环读取,大于PDUlength或AET时break * 3 根据不同类型构造并返回结果 * 4 循环接收客户端pdu */ while (true) { try { PDU pdu = null; //实例化相应PDU解析类,存储解析并pdu内容 f = true; //循环读取第一位标志 //循环读第一位,判断类型,符合类型跳出循环,解析剩余内容 while (f) { try { t = br.ReadByte(); type = t.ToString("x2"); switch (type) { case "01": { f = false; pdu = new AAssociateRQ(); break; } //修改标志,跳出循环 case "02": { f = false; pdu = new AAssociateAC(); break; } //修改标志,跳出循环 case "03": { f = false; pdu = new AAssociateRJ(); break; } //修改标志,跳出循环 case "05": { f = false; pdu = new AReleaseRQ(); break; } //修改标志,跳出循环 case "06": { f = false; pdu = new AReleaseRP(); break; } //修改标志,跳出循环 default: break; } } catch { break; } } //保存pdu类型,并打印 pdu.PDUType[0] = t; rtbLog.AppendText(pdu.Log()); //读取PDU长度 br.ReadByte(); //跳过保留位 uint length = 0; for (int i = 0; i < 4; i++) //长度占4位 { length *= 256; //左移8位 length += br.ReadByte(); } pdu.PDULength = length; //读取剩余PDU内容 byte[] pdu1 = br.ReadBytes((int)length); //分解剩余头部 pdu.PDUSplit(pdu1); rtbLog.AppendText("\nRecieved RQ PDU:" + pdu.PDUString(pdu) + "\n\n"); //比较AET pdu.pCalledAET = CalledTitle; pdu.pCallingAET = CallingTitle; pdu.AETitle(pdu); //发送结果 rtbLog.AppendText("\nSent PDU:\n"); foreach (byte i1 in pdu.r) { rtbLog.AppendText(i1.ToString("x2")); } rtbLog.AppendText("\n\n" + pdu.log); bw.Write(pdu.r); bw.Flush(); //释放关联,关闭网络流,修改网络流状态标志,跳出循环 if (type == "05") { br.Close(); bw.Close(); nets = false; break; } //重置循环解析type标志 f = true; } catch { break; } } }
//用户信息条目(固定) public AAssociateAC writeUInfo(AAssociateAC ACpdu) { ACpdu.UInfo = HexStringToByteArray("5000003B51000004000080005200001C312E322E3832362E302E312E333638303034332E322E36302E302E315500000F736F66746C696E6B5F6A6474313033"); return(ACpdu); }
//应用上下文(固定) public AAssociateAC writeAPP(AAssociateAC ACpdu) { ACpdu.App = HexStringToByteArray("10 00 0015 312E322E3834302E31303030382E332E312E312E31"); return(ACpdu); }