导航

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