シリアル化(および逆シリアル化)されるデータを表すために、構造体を使用して適切なメタデータを設定できるため、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が言ったように、いくつかのツールを使用できます。