C# 自己写的一个类,用来将结构体或类中的数据打成"数据包",进行网络发送(转载)
Posted on 2010-04-28 23:56 Happy Coding 阅读(708) 评论(0) 编辑 收藏 举报原文地址:http://www.cnblogs.com/zilong/archive/2006/03/28/361232.html
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;
}
}