I'm sending a C struct over UDP
struct packet{
int numInt;
int* intList; //malloc'ed as (sizeof(int)*numInt)
}
It will be serialized as [numInt][intList[0]]...[intList[numInt-1]]
.
My understanding is that calling recvfrom
on UDP will read the entire packet, even if the buffer doesn't hold that many bytes. Is using a really large buffer the only option I have?
You could try using a small buffer, just large enough to get
numInt
, with theMSG_PEEK
flag set. Then you can find out the size you actually need, and receive again withoutMSG_PEEK
to get the whole thing.I'm pretty sure recvfrom will read up to as many bytes as is told to it by its 3rd argument, len. If there are fewer bytes available, it will return what is there. If there are more, it will return up to len bytes. You may have to make additional calls to obtain all the data your are expecting.
You could pass
MSG_PEEK
torecvfrom
to find out exactly how big the buffer needs to be. So justrecvfrom
a few bytes withMSG_PEEK
to findnumInt
and thenrecvfrom
the real thing (this time withoutMSG_PEEK
).The standard says something about
MSG_PEEK
, but kernel.org spells it better:Obviously at some point you will start wondering if doubling the number of system calls to save memory is worth it. I think it isn't.
UDP packets are sent and received as a whole. if you receive it, the size is right. The only thing you have to do is to supply a big enough buffer on read() or recv() or recfrom(). The length field inside the payload is redundant, since the read() will tell you the correct size. It is also dangerous, since it relies on the sender and reciever having the same byte order.