C# 自己寫的一個類,用來将結構體或類中的資料打成"資料包",進行網絡發送
時間:2010-04-29 10:32 來源:未知 作者:admin 點選: 135次 我要投稿 高品質的ASP.NET空間,完美支援1.0/2.0/3.5/MVC等
using System; using System.Reflection; using System.Net; using System.Net.Sockets; using System.IO; using System.Text; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.InteropServices; namespace CSProxy { /// <summary> /// CSProxyTrans 轉換有byte,ushort,int 和 string 類型成員的結構體,并且string 類型隻是4位元組的IP位址。 /// 例: /// Login login=new Login(); /// login.Flage=1; /// login.PassWord="zzy"; /// login.State=1; /// login.UserID="zhaozhonglei"; /// /// byte[] buffer=Trans.ToBytes("jy.P2PBLL.Login",login); /// Login login2=(Login)Trans.ToStruct("jy.P2PBLL.Login",buffer); /// </summary> public class CSProxyTrans { /// <summary> /// 将成員轉化為位元組數組 /// </summary> /// <param name="thetype">類型的完全限定名,如jy.P2PBLL.Login</param> /// <param name="obj">該類型的對象</param> /// <returns>含有個格式的位元組數組</returns> public static byte[] ToBytes(string thetype,object obj) { Type type=Type.GetType(thetype); FieldInfo [] infos=type.GetFields(); byte[] buffer=new byte[10240]; int bp=0; foreach(FieldInfo fi in infos) { string a=fi.FieldType.ToString(); string b=typeof(byte).ToString(); string us=typeof(ushort).ToString(); string n=typeof(int).ToString(); string s=typeof(string).ToString(); if(a == b) { buffer[bp]=(byte)fi.GetValue(obj); bp++; } if(a == us) { byte[] uShort=BitConverter.GetBytes(IPAddress.HostToNetworkOrder((ushort)fi.GetValue(obj)));//轉化成網絡位元組順序 uShort.CopyTo(buffer,bp); bp+=2; } if(a == n) { byte[] bint=BitConverter.GetBytes((int)fi.GetValue(obj));//暫時不轉,因用來盛放一個 IP bint.CopyTo(buffer,bp); bp+=4; } if(a == s) { object O= fi.GetValue(obj); string str=(string)O; if(O!=null) { byte[] bstring=System.Text.Encoding.Unicode.GetBytes(str); int len=bstring.Length; byte[] bint=BitConverter.GetBytes(len); bint.CopyTo(buffer,bp); bp+=4; bstring.CopyTo(buffer,bp); bp+=len; } else { byte[] bint=BitConverter.GetBytes(0); bint.CopyTo(buffer,bp); bp+=4; } } } byte[] data=new byte[bp]; Array.Copy(buffer,0,data,0,bp); return data; } /// <summary> /// 得到thetype類型的對象 /// </summary> /// <param name="thetype">類型的完全限定名,如jy.P2PBLL.Login</param> /// <param name="data">含有個格式的位元組數組</param> /// <returns>thetype類型的對象</returns> public static object ToStruct(string thetype,byte [] data) { Type type=Type.GetType(thetype); FieldInfo [] infos=type.GetFields(); object obj=Activator.CreateInstance(type); int bp=0; foreach(FieldInfo fi in infos) { string a=fi.FieldType.ToString(); string b=typeof(byte).ToString(); string us=typeof(ushort).ToString(); string n=typeof(int).ToString(); string s=typeof(string).ToString(); if(a == b) { byte bval=data[bp]; fi.SetValue(obj,bval); bp+=1; } if(a == us) { ushort be=BitConverter.ToUInt16(data,bp); ushort sval=(ushort)IPAddress.NetworkToHostOrder((short)be); fi.SetValue(obj,sval); bp+=2; } if(a == n) { int val=BitConverter.ToInt32(data,bp); fi.SetValue(obj,val); bp+=4; } if(a == s) { int len=BitConverter.ToInt32(data,bp); bp+=4; if(len!=0) { string val=System.Text.Encoding.Unicode.GetString(data,bp,len); fi.SetValue(obj,val); bp+=len; } else { string val=""; fi.SetValue(obj,val); } } } return obj; } public static unsafe byte[] ToBytes(object obj) { int size = Marshal.SizeOf(obj); byte[] bytes = new byte[size]; fixed(byte* pb = &bytes[0]) { Marshal.StructureToPtr(obj,new IntPtr(pb),true); } return bytes; } /// <summary> /// 序列化 /// </summary> /// <param name="msg">結構資訊</param> /// <returns></returns> public static byte[] Serialize(object obj ) { IFormatter inFormatter = new BinaryFormatter(); MemoryStream stm = new MemoryStream(); inFormatter.Serialize(stm,obj); byte[] buffer = stm.ToArray(); stm.Close(); return buffer; } /// <summary> /// 反序列化 /// </summary> /// <param name="buffer">串行資料</param> /// <returns></returns> public static object Deserialize( byte[] buffer ) { MemoryStream stream = new MemoryStream( buffer ); BinaryFormatter outFormatter = new BinaryFormatter(); object obj = outFormatter.Deserialize( stream ); stream.Close(); return obj; } } // UDP 指令 // // +----+-----+-------+------+----------+----------+ // |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT | // +----+-----+-------+------+----------+----------+ // | 1 | 1 | X'00' | 1 | Variable | 2 | // +----+-----+-------+------+----------+----------+ public struct UdpCmd { public byte VER; public byte CMD; public byte RSV; public byte ATYP; public int DstAddr;//轉化時麻煩 public ushort DstPort; } // 應答格式 // // +----+-----+-------+------+----------+----------+ // |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT | // +----+-----+-------+------+----------+----------+ // | 1 | 1 | X'00' | 1 | Variable | 2 | // +----+-----+-------+------+----------+----------+ public struct UdpResponse { public byte VER; public byte REP; public byte RSV; public byte ATYP; public int DstAddr;//轉化時麻煩 public ushort DstPort; } // 保留2位元組的0 | 是否資料報分段重組标志 | 位址類型 | 将要發到代理外的目标位址 | 遠端目标主機的端口 | 需要通過代理傳送出去的資料 // // +----+------+------+----------+----------+----------+ // |RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA | // +----+------+------+----------+----------+----------+ // | 2 | 1 | 1 | Variable | 2 | Variable | // +----+------+------+----------+----------+----------+ public struct UdpPackageHead { public ushort RSV; public byte FRAG; public byte ATYP; public int DstAddr; public ushort DstPort; } } |