Rust中的UDP API

ust*_*ion 9 networking udp rust

1)此处发送的API返回Result<usize>.这是为什么 ?在我看来,UDP发送是全部或全部.返回值似乎表明发送可以成功,但可能不会写入整个数据,这使得我的代码如下:

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,
    }
}
Run Code Online (Sandbox Code Playgroud)

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

2) 对于读操作,虽然我明白了.我可以给它一个大小为100字节的缓冲区,但数据报可能只有50个字节长.所以基本上我应该只利用read_buf[..size_read].这里我的问题是如果缓冲区大小为100但数据报大小为150字节会发生什么?将recv_from只填写100个字节并返回Ok(100, some_peer_addr)?如果我重读,它会填写剩下的数据报吗?如果在我第二次读取之前另一个50字节的数据报到达怎么办?我是第二次得到剩余的50个字节,第三次得到50个字节的新数据报还是第二次得到100个字节,还包含新的数据报?或者将是一个错误,我将丢失我的初始读取的第一个数据报,永远无法恢复它?

Vla*_*eev 10

这两个问题的答案在于各个BSD套接字功能的文档,sendto()以及recvfrom().如果您使用某些*nix系统(例如OS X或Linux),您可以使用man sendtoman recvfrom查找它.

1)sendto()手册页对此很模糊; Windows API页面明确表示返回值可能小于len参数.另见这个问题.看起来这个特殊时刻有点不足.我认为可以安全地假设返回值总是等于或者len与错误代码相等.如果发送的数据长度sendto()超过OS内核内部缓冲区大小,则可能会出现问题,但在这种情况下,至少Windows会返回错误.

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

recvfrom()函数应返回写入缓冲区参数指向的缓冲区的消息的长度.对于基于消息的套接字,例如SOCK_RAW,SOCK_DGRAM和SOCK_SEQPACKET,应在单个操作中读取整个消息.如果消息太长而无法容纳在提供的缓冲区中,并且在flags参数中未设置MSG_PEEK,则应丢弃多余的字节.

所以是的,recv_from()将填充正好100个字节,其余将被丢弃,并进一步调用recv_from()将返回新的数据报.