LINUX.ORG.RU

recv()


0

0

Во всех ли случаях возврат 0 из recv() означает закрытие соединения ?
Зависит ли это от того блокирующий режим сокета или нет ?

anonymous

Ответ на: комментарий от anonymous

> Те в любом случае возврат из recv() 0 означает
> закрытие соединения на другом конце ?

я, вообще-то не проверял, но судя по коду
net/ipv4/tcp.c:tcp_recvmsg() есть еще один
случай, если перед recv() сделать shutdown(1)

idle ★★★★★
()
Ответ на: комментарий от idle

Ok. Спасибо. Просто странная ситуация: select() на чтение возвращает что есть чего читать, а recv() возвращает 0 и так до бесконечности :)

anonymous
()
Ответ на: комментарий от anonymous

> Просто странная ситуация: select() на чтение возвращает что есть чего читать, а recv() возвращает 0 и так до бесконечности :)

это ситуация не странная, а нормальная, на том конце закрыли соединение

lg ★★
()
Ответ на: комментарий от lg

Странно что select() возвращет что есть что читать.
У меня что-то вроде:

for(;;)
{
select();
recv();
if (все прочитали или ошибка) break;
}

Странно что select говорит что есть что читать, а recv() ноль и снова и снова. Мне почему-то казалось что в данном случае select() должен вылететь по таймауту потому что нечего читать.
Спасибо будем знать. Тем более что как я понимаю все равно возможна ситуация что select() говорит скажем что писать можно а send() обламывается потому как ситуация изменилась и уже нельзя... Вообщем использовать select() будем, а доверять ему нет :)

anonymous
()
Ответ на: комментарий от anonymous

> Странно что select говорит что есть что читать, а recv() ноль

как уже сказал lg - это нормально. и полезно.

select "говорит что есть что читать" именно
потому, что читать действительно есть что.
а именно вот эти 0 байт, которые означают,
что соединение закрыто.

иначе как бы вы об этом узнали?

idle ★★★★★
()
Ответ на: комментарий от anonymous

select() вываливается потомучто соединение закрыто. read() возвращает 0 потомучто сединение закрыто.

если сокет имеет только одину ссылку(file descriptor reference) на себя или несколько ссылок но контролируемых одним твоим процессом, и select() на запись вывалится то писать можно, буффер никуда не денется. Если же сокет шарится между процессами то действительно может возникнуть такая ситуация что select вывалился и когда ты доползешь до send() то буфера уже не будет ..

lg ★★
()

Спасибо за ответы !

anonymous
()

Вообще не помешало faq бы создать по API. Скажем о нуле в recv() нет не в man recv ни в той литературе что я читал :( Есть же еще куча моментов типа разблокирования bind() и тд и тп... Потом часто люди вообще не знают какая им нужна функция, те и сделали бы man да не знают какой.

anonymous
()
Ответ на: комментарий от lg

> если сокет имеет только одину ссылку(file descriptor reference)
> и select() на запись вывалится то писать можно, буффер никуда не денется.

нет. очень даже может деться. да и буфера там нет.

в соседней ветке, 'Отмена буферизации на сокете',
я писал об этом.

select скажет, что писать можно, когда sk_sndbuf > sk_wmem_queued,
а собственно память будет выделяться уже при посылке, а ее
может не быть, и тогда EAGAIN.

idle ★★★★★
()
Ответ на: комментарий от idle

ну это то да. любая рутина может во время send() обломаться ..

я про то что пока доберется до send() может такое случится что что wmem_queued уже будет больше(равен?) sndbuf, хотя на момент вываливания select() это было не так

кстати select() помоему вываливается когда tcp_wspace()>tcp_min_write_space() и это не одно и тоже что sndubf>wmem_queued ..

lg ★★
()
Ответ на: комментарий от lg

> кстати select() помоему вываливается когда tcp_wspace()>tcp_min_write_space()
> и это не одно и тоже что sndubf>wmem_queued

да, это будет вернее.

idle ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.