Networking - std::net::UdpSocket

  1. API for send here returns Result<usize>. Why is that ? In my head, a UDP send is all or none. The return value seems to suggest that sending can succeed but entire data may not be written which makes me code like:

    let mut bytes_written = 0;
    while bytes_written < data.len() {
    bytes_written += match udp_socket.send_to(&data[bytes_written..]) {
    Ok(bytes_tx) => bytes_tx,
    Err(_) => break,

Recently someone told me this is completely unnecessary. But I don't understand. If that were true why is the return not Result<()> instead, which is also what i was expecting ?

For reads though I understand. I could give it a buffer of size 100 bytes but the datagram might only be 50 bytes long. So essentially I should utilise only read_buf[..size_read]. Here my question is what happens if the buffer size is 100 but the datagram size is say 150 bytes ? Will recv_from fill in only 100 bytes and return Ok(100, some_peer_addr) ? If i re-read will it fill in the remaining of the datagram ? What if another datagram of 50 bytes arrived before my second read ? Will i get just the remaining 50 bytes the second time and 50 bytes of new datagram the 3rd time or complete 100 bytes the 2nd time which also contains the new datagram ? Or will be an error and i will lose the 1st datagram on my initial read and never be able to recover it ?

The underlying system call returns the number of bytes sent and we simply forward that along.

Each call to recv_from will read a single datagram. If the message is longer than the buffer, the first portion will be copied into your buffer, and the trailing portion will be discarded.

1 Like

Can you also pls explain the rationale behind the underlying system call returning that. I would be interested in knowing that, plus that would complete the answer as well. In light of underlying sys call returning size, do you think we are supposed to code the way I did in 1) or is the return value of size of absolutely no use ?

The same set of system calls, send and sendto, are used for all types of network sockets, including TCP and UDP sockets. While the return value may not be super meaningful in the case of UDP, it is meaningful for TCP sockets, where you have to worry about short writes.

I also wouldn't be surprised to see that UDP sockets could return short writes in extreme circumstances (e.g. a gigabyte write call).

1 Like