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; } } |