Потеря байтов в неблокирующем сокете, контролируемом epoll, когда другая сторона записывает и закрывает

В настоящее время у меня есть неблокирующий сокет:

 ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP | EPOLLRDHUP| EPOLLET;

Он получает пару EPOLLIN, которые я читаю без блокировки до EAGAIN, а затем я получаю HUP и RDHUP, иногда с еще несколькими байтами для чтения.

Другая сторона просто:

send(socket,960_bytes_buffer)
close(socket);

Я пробовал recv с msg_peek непосредственно в цикле событий как для epollin, так и для близкого времени, и добавляя полученные данные, он не всегда получает 960, иногда только около 480 байт.

Создание неблокирующего сокета или установка режима сна (1) в клиенте между отправкой и закрытием работает нормально.

Мне кажется, это больше проблема неблокирующих сокетов, чем проблема, связанная с epoll. Что-то простое, например «nc -l -p port», получает нужное количество байтов.


person Arkaitz Jimenez    schedule 13.10.2009    source источник
comment
Проверяете ли вы события на наличие битов HUP перед проверкой бита IN?   -  person Nikolai Fetissov    schedule 13.10.2009
comment
Да, и в любом случае после HUP я закрываю () и перед закрытием проверяю ожидающие данные   -  person Arkaitz Jimenez    schedule 13.10.2009
comment
Как вы проверяете ожидающие данные?   -  person Nikolai Fetissov    schedule 13.10.2009
comment
Только с MSG_PEEK recv должен сообщить вам, сколько байтов еще осталось в буфере приема. Кроме того, почему бы просто не прочитать POLLIN и нормально обработать eof при нулевом возврате?   -  person Nikolai Fetissov    schedule 13.10.2009


Ответы (1)


Взгляните на Последнюю страницу SO_LINGER, или: почему мой TCP ненадежен, которая прекрасно объясняет что происходит и как это исправить.

person cmeerw    schedule 13.10.2009