Reputation: 9259
i use a UDP-socket for sending/receiving objects. I serialize the objects into a byte array send it and receive it with a client. But before i can receive i have to allocate a byte array. I must do it before and then handle the Socket.Receive()-methode the array. But my objects have a variable length. How can i discover the array-size?
Thank you
Edit: Here a example of my receive-methode:
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);
}
Upvotes: 2
Views: 9146
Reputation: 9625
The most typical method of doing this involves something along the lines of having the first few bytes of a data chunk be the chunk length.
So, for example, if your object size is always under 65k or there abouts, you could send the array size through the socket first as a short (Look at using the BitConverter class). The receiver would read the first chunk it receives into a buffer (probably one roughly the size of a nominal UDP packet, somewhere around 512 bytes), grab the first two bytes, convert them to a short, and set up the buffer for the object. It would then continue to read from the socket until that buffer is full, and pass that buffer off to the de-serializer.
This of course doesn't cover error handing and such, but it's the basic idea.
EDIT:
It's been awhile since I did anything with UDP in .Net, but something like this might work (In somewhat psuedocode)
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
}
}
}
That's the basic process, ignoring locking due to multiple threads (which you will have to deal with since Receive bocks), and reading and writing from different spots in the memory stream. Hopefully this is enough to get you going in the right direction.
Upvotes: 3
Reputation: 46034
Chances are you're dealing with typical UDP packets which are limited to a size of 64k, or 65535 bytes. Allocate a 64k-byte array and pass that to the Receive()
function. Assuming a typical socket implementation, the Receive()
function will return the number of bytes that were actually received.
Upvotes: 3