爲了表示要序列化的數據(和反序列化),可以使用一個結構,並設置適當的元數據,所以CLR會爲您完成剩下的工作。像其他人說的,在這裏你需要處理終點上的數據包接收。你也必須考慮接收者期望的字符集,因爲你的數據中有一個字符串字段。以下代碼是關於如何實現結構以將託管數據轉換爲二進制格式和帶註釋的示例。
// setting the layout to sequential will prevent the compiler/JIT
// to reorder the struct fields
// NOTE: Observe here that the Charset used is Ansi. You may need to
// change this depending on the format expected by the receiver.
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct DataPacket
{
[MarshalAs(UnmanagedType.U4)]
public uint Id;
// As I understood from your question, the Name field
// has a prefixed size of 40 bytes. Attention here:
// the SizeConst actually means '40 characters', not bytes
// If you choose to use the Unicode charset, set SizeConst = 20
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)]
public String Name;
// This will be serialized in little endian format
// in your question this field is 8 bytes long, which
// in c# corresponds to the double type. If you really mean
// the float type (4 bytes), change here.
public double Grade;
// Calling this method will return a byte array with the contents
// of the struct ready to be sent via the tcp socket.
public byte[] Serialize()
{
// allocate a byte array for the struct data
var buffer = new byte[Marshal.SizeOf(typeof(DataPacket))];
// Allocate a GCHandle and get the array pointer
var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
var pBuffer = gch.AddrOfPinnedObject();
// copy data from struct to array and unpin the gc pointer
Marshal.StructureToPtr(this, pBuffer, false);
gch.Free();
return buffer;
}
// this method will deserialize a byte array into the struct.
public void Deserialize(ref byte[] data)
{
var gch = GCHandle.Alloc(data, GCHandleType.Pinned);
this = (DataPacket)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(DataPacket));
gch.Free();
}
}
用法:
DataPacket packet;
packet.Id = 1234;
packet.Name = "Marvin the paranoid robot";
packet.Grade = 9.2;
// serialize
var bytes = packet.Serialize();
// send via tcp
var tcp = new TcpClient(...);
tcp.GetStream().Write(bytes, 0, bytes.Length);
// deserializing;
DataPacket receivedPacket;
receivedPacket.Deserialize(bytes);
您已經擁有了包,現在你需要處理接收器上的數據包接收。這部分你不需要手工完成,你可以使用一些工具,比如@jgauffin說的。
坦率地說,我不會在這裏尋找任何特別的東西;我只讀了49個字節,然後通過偏移量手動選取它們... – 2012-08-15 13:19:46