要表示要序列化(和反序列化)的数据,您可以使用结构并设置正确的元数据,因此 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 说的。