gpt4 book ai didi

C# 在通过 TCP 接收结构后反序列化结构

转载 作者:可可西里 更新时间:2023-11-01 02:57:56 26 4
gpt4 key购买 nike

我正在通过 C# 为 TCPListener 和 TCPClient 提供的 TCP 接口(interface)发送我自己的结构“数据包”对象。

这是我的结构

[Serializable]
struct RemuseNetworkPacket
{
public String ApplicationCode;
public String ReceiverCode;
public RemusePacketType Type;
public uint ID;
public uint cID;
public String Name;
public byte[] Data;
public String Text;
public System.Drawing.Point Coords;
public String Timestamp;
public String Time;
public String SenderName;

public byte[] Serialize()
{
var buffer = new byte[Marshal.SizeOf(typeof(RemuseNetworkPacket))];
var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
var pBuffer = gch.AddrOfPinnedObject();
Marshal.StructureToPtr(this, pBuffer, false);
gch.Free();
return buffer;
}

public void Deserialize(byte[] data)
{
var gch = GCHandle.Alloc(data, GCHandleType.Pinned);
this = (RemuseNetworkPacket)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(RemuseNetworkPacket));
gch.Free();
}
}

我在结构中使用序列化方法在发送前后准备和检索数据。

为了让接收方知道传入数据的大小,我在发送的字节中添加了一些 header 数据,格式为 l=212;... 这意味着长度 = 212 ; ... 是数据包的其余部分。

在接收端我搜索这个直到找到整个 l=xxxx;然后我创建一个没有标题的新字节数组,然后尝试反序列化数据。用于反序列化的数据包字节是:tcp 流的 buffer.Length - foundHeaderSize (l=xxxx;)

如果我在同一台机器上运行客户端和服务器,它可以正常工作,但是如果我在不同的机器上运行客户端和服务器,我会遇到异常并崩溃。

异常发生在数据包被反序列化时,说:

*System.Runtime.InteropServices.SafeArrayTypeMismatchException数组的运行时类型与元数据中记录的 sb 类型之间发生不匹配System.Runtime.InteropServices.PtrToStructureHelper

堆栈跟踪:System.Runtime.InteropServices.PtrToStructureHelper(IntPtr ptr, Object structure, Boolean allowValueClasses) 在System.Runtime.InteropServices.PtrToStructure(IntPtr ptr,类型 structureType..*

我正在寻求帮助以确定问题的原因。我不能对通过网络传入的对象这样做吗?

最佳答案

与其让一个字符串代表您的数据包长度,然后减去该字符串的长度以了解从哪里开始读取,不如实现适当的长度前缀。长度前缀结合数据头将使您能够根据每个数据包的大小读取每个数据包,然后数据头将帮助您确定如何处理数据。

普通的长度前缀会为您发送的每个“数据包”添加一个固定的 header 。要创建此 header ,请将整数(数据的长度)转换为字节,这将产生 4 个字节,然后在其后添加数据 header 以及数据包的其余部分(这是您要发送的数据) .

这将创建以下数据包结构:

[Length (4 bytes)][Header (1 byte)][Data (x byte(s))]

读取数据包非常简单:

  1. 读取前 4 个字节(Length),将它们转换并赋值给一个整型变量。

  2. 读取下一个字节(数据头)并将其放入变量中。

  3. 读取 x 字节到字节数组(其中 x 是您在步骤 1 中声明的整数)。

  4. 使用第 2 步中的数据 header 来确定如何处理您的数据(第 3 步中的字节数组)。

my previous answers 之一中你可以看到我刚才解释的例子。

关于C# 在通过 TCP 接收结构后反序列化结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37341382/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com