我使用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);
}
答案 0 :(得分:3)
最常见的方法是将数据块的前几个字节作为块长度。
因此,例如,如果您的对象大小始终低于65k或大约,您可以首先通过套接字发送数组大小作为简短(使用BitConverter类查看)。接收器将其接收到的第一个块读入缓冲区(可能大约是标称UDP数据包的大小,大约512字节),获取前两个字节,将它们转换为short,并为对象设置缓冲区。然后它将继续从套接字读取,直到缓冲区已满,并将该缓冲区传递给反序列化器。
这当然不包括错误处理等,但这是基本的想法。
编辑:
自从我在.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
}
}
}
这是基本过程,忽略了由于多个线程(自接收块以来你必须处理)的锁定,以及从内存流中的不同位置读取和写入。希望这足以让你朝着正确的方向前进。
答案 1 :(得分:3)
您可能正在处理典型的UDP数据包,其大小限制为64k或65535字节。分配一个64k字节的数组并将其传递给Receive()
函数。假设一个典型的套接字实现,Receive()
函数将返回实际接收的字节数。