2016-01-27 21 views
7

1) API for send here restituisce Result<usize>. Perché ? Nella mia testa, un invio UDP è tutto o nessuno. Il valore di ritorno sembra suggerire che l'invio può avere successo, ma tutti i dati non può essere scritto che mi rende il codice come:API UDP in Rust

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

Recentemente qualcuno mi ha detto che questo è completamente inutile. Ma non capisco. Se fosse vero perché il ritorno non è Result<()>, che è anche quello che mi aspettavo?

2) For reads anche se ho capito. Potrei dargli un buffer di dimensioni 100 byte ma il datagramma potrebbe essere lungo solo 50 byte. Quindi essenzialmente dovrei utilizzare solo read_buf[..size_read]. Qui la mia domanda è cosa succede se la dimensione del buffer è 100 ma la dimensione del datagramma è di 150 byte? Sarà recv_from riempire solo 100 byte e restituire Ok(100, some_peer_addr)? Se rileggo, riempirà il resto del datagramma? Cosa succede se un altro datagramma di 50 byte è arrivato prima della mia seconda lettura? Riceverò solo i restanti 50 byte la seconda volta e 50 byte del nuovo datagrammo la terza volta o completerò 100 byte la seconda volta che contiene anche il nuovo datagramma? O sarà un errore e perderò il 1 ° datagramma nella mia lettura iniziale e non sarò mai in grado di recuperarlo?

risposta

9

La risposta a entrambe queste domande si trova nella documentazione delle rispettive funzioni socket BSD, sendto() e recvfrom(). Se si utilizza un sistema * nix (OS X o Linux, ad esempio), è possibile utilizzare man sendto e man recvfrom per trovarlo.

1) sendto() la pagina di manuale è piuttosto vaga su questo; La pagina API Windows indica esplicitamente che è possibile che il valore restituito sia inferiore all'argomento len. Vedi anche la domanda this. Sembra che questo particolare momento sia in qualche modo poco documentato. Penso che sia probabilmente sicuro assumere che il valore restituito sarà sempre uguale a len o al codice di errore. Possono verificarsi problemi se la lunghezza dei dati inviati tramite sendto() supera la dimensione del buffer interno all'interno del kernel del sistema operativo, ma sembra che almeno Windows restituirà un errore in questo caso.

2) recvfrom() pagina man afferma in modo inequivocabile che la parte di un datagramma che non rientra nel buffer sarà scartato: la funzione

La recvfrom() deve restituire la lunghezza del messaggio scritta al buffer puntato dall'argomento buffer. Per i socket basati su messaggio , come SOCK_RAW, SOCK_DGRAM e SOCK_SEQPACKET, l'intero messaggio deve essere letto in un'unica operazione . Se un messaggio è troppo lungo per adattarsi al buffer fornito, e MSG_PEEK non sono impostati nell'argomento flags, i byte in eccesso devono essere eliminati da .

Quindi sì, recv_from() riempirà esattamente 100 byte, il resto verrà scartato, ed ulteriori chiamate a recv_from() torneranno nuovi datagrammi.

2

Se si dig down, si sta semplicemente avvolgendo il C sendto function. Questa funzione restituisce il numero di byte inviati, quindi Rust lo passa (mentre gestisce il caso -1 e trasforma errno in errori effettivi).