C 'recv' с MSG_PEEK не возвращает -1

Я пишу функцию C, чтобы проверить, доступно ли соединение сокета от клиента. Я использую функцию recv с MSG_PEEK, чтобы не изменять входной буфер.

Однако, когда соединение сокета закрывается клиентом, 'recv' должен возвращать -1, но это не так. После закрытия клиента 'recv' в приведенной ниже функции всегда возвращает 0.

char is_avail(int connection) {
  char buffer;

  int result = recv(connection,&buffer,1,MSG_PEEK);
  if (result<0)
    return 0;
  else
    return 1;
}

Любая причина для этого вопроса? а также я хочу объединить MSG_PEEK с MSG_WAITALL. Я пытался:

recv(connection,&buffer,1,MSG_PEEK|MSG_WAITALL);

но это не вступает в силу.


person jondinham    schedule 21.08.2012    source источник
comment
проверьте, доступно ли соединение сокета от клиента Вы вызываете recv на сокете, на котором вы вызывали listen ?   -  person cnicutar    schedule 21.08.2012
comment
Не используйте MSG_WAITALL, так как он будет заблокирован, пока не сможет выполнить ваш запрос. Таким образом, он будет блокироваться до тех пор, пока не появятся данные для чтения (или просмотра в вашем случае), что теоретически может быть навсегда.   -  person Some programmer dude    schedule 21.08.2012
comment
@JoachimPileborg На самом деле, recv уже делает это по умолчанию, если только сокет не установлен на «неблокирующий». В любом случае MSG_WAITALL в этом случае бессмысленна, так как она будет ждать, пока не будет прочитан 1 байт... что равно количеству байтов, которых она ожидает без MSG_WAITALL.   -  person ATaylor    schedule 21.08.2012
comment
MSG_PEEK и общая проверка isAvailable из сокетов — плохая идея. Он заслужил место в списке хромых программистов Winsock из-за своей изначально ненадежной природы. Не используйте PEEK, просто немедленно скопируйте все данные в свои собственные буферы.   -  person kert    schedule 01.09.2014
comment
@kert довольно старый комментарий .. однако в настоящее время я рассматриваю возможность изменения протокола с буферов фиксированного размера на сообщения с динамическим размером, и мне были бы интересны любые плюсы и минусы MSG_PEEK, знаете ли вы какие-либо ресурсы по теме?   -  person 463035818_is_not_a_number    schedule 22.06.2017


Ответы (1)


recv НЕ возвращает -1, когда сокет закрыт правильно, а скорее «0».

0 -> изящное закрытие сокета

-1-> Произошла реальная ошибка

› 0-> Данные считаны.

person ATaylor    schedule 21.08.2012
comment
@PaulDinh Нет, это не так. Если нет данных для чтения, он вообще не возвращается. Он блокируется до тех пор, пока не появятся данные для чтения. Исключение из этого: когда вы настраиваете сокет как неблокирующий. В этом случае recv вернет -1, если данных нет. Единственный раз, когда recv вернет «0», это когда соединение фактически закрыто. - person ATaylor; 21.08.2012
comment
мой сокет не блокируется, я настраиваю его с помощью fcntl (socket, F_SETFL, O_NONBLOCK); но «recv» возвращает 0, это все еще исключение - person jondinham; 21.08.2012
comment
@PaulDinh Пробовали ли вы проверить с помощью Wireshark, правильно ли установлено соединение и не разорвано ли оно тем временем? Розетка подключена, верно? Потому что «0» в конце концов означает «закрытое соединение». - person ATaylor; 21.08.2012