Reading from UDP socket blocks even if there is data

Hi everyone!
I hope you can help me out on this one.

I have to read a fixed number of bytes from a UDP connection (it’s the header of a custom packet), make room for the content in a buffer and then read again from the network buffer as to process the whole packet.
The problem is my code hangs at the second Read(), can’t figure out why since there is still data to read packed in the network buffer.

Here’s the code (only the useful bits)

    //make room for the packet header
    headerBuf := make([]byte, ndnDataPacketHeader)
    // read just the header from the network buffer
    headerSize, err := conn.Read(headerBuf)
    //...parsing the header (stripped from this post)
    // store the payload
    payloadBuf := make([]byte, int(nameLength)+int(contentLength))
    payloadSize, err := conn.Read(payloadBuf)

A read from an UDP socket reads exactly one datagram. If you provide a buffer that is smaller than that datagram the rest of the data is discarded.

For your purposes, simply read into a buffer that is as large as the largest expected message (or 65507 bytes). Then parse it as appropriate.

(So what currently happens for you is that you read part of the first datagram, the rest gets discarded, then on the next read you block waiting for another datagram.)

1 Like

Thank you! I could not find anything about this in the docs therefore I just thought it would’ve worked like in C.

Do you know any way of reading the UDP packet allocating just as much memory as needed?

Not unless you know the max size up front. But an UDP message can’t be larger than 65507 bytes, so that’s the absolute max. Given that, I usually just take that cost once up front:

const maxMessageSize = 65507 // max UDP message size, unless you know better

// ...

bs := make([]byte, maxMessageSize)
for {
  n, err := conn.Read(bs)
  // unmarshal and handle bs[:n]
  // ...

Since the buffer is reused for every read it’s quite cheap.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.