2013-05-10 24 views
6

Z podręcznika epoll_ctl:Biorąc pod uwagę każde zdarzenie gniazda TCP epoll, jeśli EPOLLRDHUP = 0 i EPOLLIN = 1; to jest kolejne wywołanie read()/recv() gwarantowane, aby zwrócić rozmiar odczytu nie równy 0?

EPOLLRDHUP (od wersji Linuksa 2.6.17)

Stream wzajemnej gniazdo zamknięte połączenie lub wyłączyć pisanie połowę połączenia. (Flaga ta jest szczególnie przydatna do pisania prosty kod do wykrywania wzajemnej wyłączenie przy użyciu wyzwalany zboczem monitoringu.)

Z podręcznika recv:

Jeśli żadne komunikaty są dostępne do pobrania oraz peer występował procedurę zamykania, recv() zwraca 0.

wydaje mi się więc, że oba powyższe pokrywy te same scenariusze, i że tak długo, jak złapać wydarzenia EPOLLRDHUP pierwszy, ja nigdy nie powinny otrzymują read() lub recv() o długości 0 (a więc nie potrzebują t o sprawdzać takie). Ale czy to jest zagwarantowane?

Odpowiedz

6

Jeśli otrzymasz zdarzenie z EPOLLRDHUP=1, po prostu zamknij połączenie natychmiast, bez czytania. Jeśli pojawi się zdarzenie z EPOLLRDHUP=0 i EPOLLIN=1, to śmiało czytaj dalej, ale powinieneś być przygotowany na to, że na wypadek, gdy nadal będziesz zwracał 0, nadal będziesz mieć 0. Być może FIN przybywa po otrzymaniu EPOLLIN=1, ale zanim zadzwonisz pod numer recv().

+2

"Być może FIN przybywa po tym, jak otrzymałeś EPOLLIN = 1, ale zanim zadzwonisz recv()." Ale nawet jeśli FIN pojawi się w takiej chwili, recv() zwróci coś większego niż 0, prawda? Ponieważ rura FIFO nadal zawiera cokolwiek wywołaną EPOLLIN = 1. – Will

+0

Świetna odpowiedź. Zmieniłbym go tak, by powiedział: "... czytaj dalej, ale powinieneś być przygotowany na to, że recv() nadal będzie zwracał 0 ** lub -1 **, na wszelki wypadek". – selbie

+0

@selbie Oczywiście powinienem zrobić i sprawdzić -1 (zarówno dla EAGAIN, jak i różnych nagłych błędów). Ponadto, mimo że procedura opisana w tej odpowiedzi może być najlepsza i najbezpieczniejsza (i robię to dokładnie w moim bieżącym kodzie), to * nie * jest świetną odpowiedzią, ponieważ nie daje satysfakcjonującej odpowiedzi na * dlaczego * Muszę sprawdzić na 0 (w wyżej wspomnianym scenariuszu). – Will