2016-01-27 15 views
7

1) API for send hereResult<usize>. Почему это ? В моей голове UDP-передача - это все или ничего. Возвращаемое значение, кажется, предполагает, что передача может быть успешным, но все данные не могут быть записаны, что делает меня такой код:UDP API в ржавчине

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

Недавно кто-то сказал мне, что это совершенно не нужно. Но я не понимаю. Если бы это было так, почему вместо этого было возвращено не Result<()>, чего я ожидал?

2) For reads хотя я понимаю. Я мог бы дать ему буфер размером 100 байт, но датаграмма может быть длиной всего 50 байт. Поэтому по существу я должен использовать только read_buf[..size_read]. Здесь мой вопрос, что произойдет, если размер буфера равен 100, а размер дейтаграммы - 150 байт? Будет ли recv_from заполнить всего 100 байт и вернуть Ok(100, some_peer_addr)? Если я перечитаю, он заполнит оставшуюся датаграмму? Что, если другая датаграмма из 50 байт прибыла до моего второго чтения? Я получу только оставшиеся 50 байт во второй раз и 50 байт новой датаграммы в 3-й раз или полные 100 байт во второй раз, который также содержит новую датаграмму? Или будет ошибка, и я потеряю первую дейтаграмму в своем первоначальном чтении и никогда не смогу ее восстановить?

ответ

9

Ответ на оба этих вопроса заключается в документации соответствующих функций сокетов BSD, sendto() и recvfrom(). Если вы используете некоторую систему * nix (например, OS X или Linux), вы можете использовать man sendto и man recvfrom, чтобы найти ее.

1) sendto() справочная страница довольно расплывчата по этому поводу; Windows Страница API явно указывает, что возвращаемое значение может быть меньше аргумента len. См. Также this вопрос. Похоже, что этот конкретный момент несколько задокументирован. Я думаю, что, вероятно, можно с уверенностью предположить, что возвращаемое значение всегда будет равно либо len, либо коду ошибки. Проблемы могут возникнуть, если длина данных, отправленных через sendto(), превышает внутренний размер буфера внутри ядра ОС, но кажется, что по крайней мере Windows вернет ошибку в этом случае.

2) recvfrom() людей страница однозначно заявляет, что часть дейтаграммы, которая не помещается в буфер будет отброшена: функция

recvfrom() возвращает длину сообщения записываются в буфер, на который указывает аргумент buffer. Для сокетов на основе сообщений, таких как SOCK_RAW, SOCK_DGRAM и SOCK_SEQPACKET, все сообщение должно считываться в одной операции . Если сообщение слишком длинное для размещения в поставляемом буфере, и MSG_PEEK не установлены в аргументе flags, избыточные байты должны быть отброшены .

Так что да, recv_from() заполнит ровно 100 байт, остальные будут отброшены, а также призывает к recv_from() будет возвращать новые датаграммы.

2

Если вы dig down, это просто упаковка C sendto function. Эта функция возвращает количество отправленных байтов, поэтому Rust просто передает это значение (при обработке случая -1 и превращении errno в фактические ошибки).

Смежные вопросы