天天看點

C# 一個類用來将結構體或類中的資料打成"資料包",進行網絡發送

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;

 }

}