我使用 UDP 套接字来发送/接收对象。 我将对象序列化为字节数组,发送它并通过客户端接收它。 但在我可以接收之前,我必须分配一个字节数组。我必须先执行此操作,然后处理数组的 Socket.Receive() 方法。 但我的对象的长度是可变的。我如何发现数组大小?
谢谢
编辑:这是我的接收方法的示例:
BinaryFormatter bf = new BinaryFormatter();
public Object ReceiveUdpPacket()
{
byte[] objData = new byte[bufferSize];
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 0);
EndPoint ep = (EndPoint)ipep;
MemoryStream ms = new MemoryStream();
udpSocket.ReceiveFrom(objData, ref ep);
ms.Write(objData, 0, objData.Length);
ms.Seek(0, SeekOrigin.Begin);
return (Object)bf.Deserialize(ms);
}
最佳答案
执行此操作的最典型方法涉及将数据 block 的前几个字节作为 block 长度。
因此,例如,如果您的对象大小始终低于 65k 或大约,您可以首先通过套接字将数组大小作为短消息发送(查看使用 BitConverter 类)。接收方会将其接收到的第一个 block 读入缓冲区(可能大约是标称 UDP 数据包的大小,大约 512 字节),抓取前两个字节,将它们转换为短字节,并为对象设置缓冲区。然后,它将继续从套接字读取数据,直到缓冲区已满,并将该缓冲区传递给反序列化器。
这当然不包括错误处理等,但这是基本思想。
编辑:
自从我在 .Net 中使用 UDP 做任何事情以来已经有一段时间了,但是类似的东西可能会起作用(在某种程度上伪代码中)
var bigBuffer = new MemoryStream();
//This should be run in a thread
void UdpLoop()
{
while(!done)
{
var buffer = udpClient.Receive();
bigBuffer.Write(buffer,buffer.Length);
}
}
void MessageProcessor()
{
var messageLength = 0;
while(!done)
{
if(bigBuffer.Length > 0 && messageLength == 0)
{
var lengthBytes = new byte[2];
bigBuffer.Read(lengthBytes, 2);
messageLength = BitConverter.ToInt16(lengthBytes);
}
if(messageLength > 0 && bigBuffer.Length > messageLength)
{
var objectBuffer = new byte[messageLength];
bigBuffer.Read(objectBuffer, messageLength);
//Do deserialization here
}
}
}
这是基本过程,忽略由于多个线程而导致的锁定(自接收 block 以来您必须处理这些锁定),以及从内存流中的不同位置读取和写入。希望这足以让您朝着正确的方向前进。
关于arrays - C# : UDP Socket - Receive data with unknown size,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3687193/