Rust 中的 UDP API

UDP API in Rust

1) API for send here returns Result<usize>。这是为什么 ?在我看来,UDP 发送是全部或 none。 return 值似乎表明发送可以成功,但可能不会写入整个数据,这让我的代码如下:

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,
    }
}

最近有人告诉我这是完全没有必要的。但我不明白。如果那是真的,为什么 return 而不是 Result<()>,这也是我所期待的?

2) For reads虽然我明白了。我可以给它一个大小为 100 字节的缓冲区,但数据报可能只有 50 字节长。所以基本上我应该只使用 read_buf[..size_read]。我的问题是,如果缓冲区大小为 100 但数据报大小为 150 字节,会发生什么情况?会 recv_from 只填写 100 个字节和 return Ok(100, some_peer_addr) 吗?如果我重新阅读它会填充数据报的剩余部分吗?如果在我第二次读取之前另一个 50 字节的数据报到达怎么办?我第二次只得到剩余的 50 个字节,第三次得到 50 个字节的新数据报,还是第二次得到完整的 100 个字节,其中也包含新数据报?或者将是一个错误,我将在初始读取时丢失第一个数据报并且永远无法恢复它?

这两个问题的答案都在相应 BSD 套接字函数 sendto()recvfrom() 的文档中。如果你使用一些 *nix 系统(例如 OS X 或 Linux),你可以使用 man sendtoman recvfrom 来找到它。

1) sendto() 手册页对此相当模糊; Windows API page explicitly says that it is possible for the return value be less than len argument. See also this 问题。看起来这个特殊的时刻有点under-documented。我认为假设 return 值将始终等于 len 或错误代码可能是安全的。如果通过 sendto() 发送的数据长度超过 OS 内核内部缓冲区大小,可能会出现问题,但似乎至少 Windows 会 return 出错这种情况。

2) recvfrom() 手册页明确指出不适合缓冲区的数据报部分将被丢弃:

The recvfrom() function shall return the length of the message written to the buffer pointed to by the buffer argument. For message-based sockets, such as SOCK_RAW, SOCK_DGRAM, and SOCK_SEQPACKET, the entire message shall be read in a single operation. If a message is too long to fit in the supplied buffer, and MSG_PEEK is not set in the flags argument, the excess bytes shall be discarded.

所以是的,recv_from() 将恰好填充 100 个字节,其余的将被丢弃,进一步调用 recv_from() 将 return 新数据报。

如果你dig down, it just wrapping the C sendto function。这个函数 returns 发送的字节数,所以 Rust 只是传递它(同时处理 -1 情况并将 errno 转换为实际错误)。