2013-05-10 8 views
6

Dal manuale di epoll_ctl:Dato un evento socket epoll TCP, se EPOLLRDHUP = 0 ed EPOLLIN = 1; è una successiva chiamata a read()/recv() garantita per restituire una dimensione di lettura non uguale a 0?

EPOLLRDHUP (a partire da Linux 2.6.17)

Flusso presa peer, o spegnere crei metà di collegamento chiusa. (Questo flag è particolarmente utile per la scrittura di codice semplice per rilevare l'arresto dei pari quando si utilizza Bordo monitoraggio Triggered.)

Dal manuale di recv:

Se non ci sono messaggi disponibili da ricevere e il peer ha eseguito un arresto regolare, recv() deve restituire 0.

mi sembra allora che entrambi del coperchio sopra gli stessi scenari, e che fino a quando mi cattura eventi EPOLLRDHUP prima, non avrei mai ricevere read() o recv() di lunghezza 0 (e quindi non hanno bisogno di t o preoccuparsi di controllarlo). Ma è garantito che sia vero?

risposta

6

Se ricevi un evento con EPOLLRDHUP=1, chiudi subito la connessione senza leggere. Se ricevi un evento con EPOLLRDHUP=0 e EPOLLIN=1, vai avanti e leggi, ma dovresti essere pronto a gestire la possibilità di recv() restituendo ancora 0, per ogni evenienza. Forse un FIN arriva dopo aver ottenuto EPOLLIN=1 ma prima di chiamare effettivamente recv().

+2

"Forse arriva FIN dopo aver ottenuto EPOLLIN = 1 ma prima di chiamare effettivamente recv()." Ma anche se un FIN arriverà in quel momento, recv() restituirà qualcosa più grande di 0, giusto? Perché la pipa FIFO contiene ancora tutto ciò che ha provocato EPOLLIN = 1 in primo luogo. – Will

+0

Ottima risposta. Vorrei modificarlo per dire "... vai avanti e leggi, ma dovresti essere pronto a gestire la possibilità che recv() restituisca ancora 0 ** o -1 **, per ogni evenienza." – selbie

+0

@selbie Ovviamente dovrei controllare per -1 (sia per EAGAIN che per gli errori improvvisi vari). Inoltre, anche se la procedura descritta in questa risposta potrebbe essere la migliore e la più sicura (e faccio esattamente questo nel mio codice attuale), non è * una * ottima risposta, perché non fornisce una risposta soddisfacente per * perché * Devo controllare per 0 (nello scenario sopra citato). – Will

Problemi correlati