Эксперимент с неблокирующимися сокетами (block socket gcc example)
Ключевые слова: block, socket, gcc, example, (найти похожие документы)
Date: Wed, 05 Mar 2003 09:53:51 +0500
From: Valentin Nechayev <netch@segfault.kiev.ua>
Newsgroups: ftn.ru.unix.prog
Subject: Эксперимент с неблокирующимися сокетами
>> Я уже посоветовал. Про треды ничего сказано не было.
AP> Угу. А если у меня уже взведён другой обработчик алармов? аларм -- криво как
AP> ни крути.
Случай другого обработчика, кажется, рассмотрен в sendmail'е, там это
обходится через setitimer() сохранением старого состояния и восстановлением
по сигналу. В общем, методы есть.
>> А вообще, повтори plz ещё раз ситуацию. Ты хочешь, чтобы на сокете,
>> который или ещё не прошёл connect(), или уже не прошёл (refused, и тому
>> подобное), read() выдавал что-то осмысленное?
AP> Я хочу быть уверенным, что неблокирующийся сокет прошёл коннект. Вроде
AP> приведённый мной код должен делать именно это.
Если 1) сокет сделан неблокирующим, 2) сделан connect(), 3) дождались
возможности записи, и вот тут возникает проблема определить, получился
успешный коннект или нет? Проверка на неблокируемость чтения и записи
проходит на оба успешно, потому что они потом вылетят с ошибкой?
Я правильно описал, чего ты хочешь?
Вот отчёт теста (код - ниже):
netch@iv:~/prog/tests/sockets/connect>./c
scheck(RW): after poll: not ready for anything
now is 1046846925:031937
on connect: -1,36
c: getpeername: Socket is not connected
now is 1046846925:032188
Connect is in progress
scheck(RW): after poll: not ready for anything
sget: -1,Resource temporarily unavailable(35)
now is 1046846925:032241
scheck(RW): after poll: ready for write
sget: -1,Resource temporarily unavailable(35)
now is 1046846925:170563
peer: 0xC1C1C104:22
scheck(R): after poll: ready for read
sget: 40,Resource temporarily unavailable(35)
now is 1046846925:307460
Видно, что:
1. Прямым критерием того, что коннект есть, является положительный ответ
getpeername().
2. По connect() ушёл SYN, готовности нет ни к чему, а мы пошли в спячку.
getpeername() пока говорит, что ничего нет. Спячка заканчивается приходом
пакета SYN+ACK, после чего немедленно возникает готовность к записи.
3. Готовность к чтению возникает уже на четвёртом пакете - когда со стороны
сервера прошёл PSH+ACK с данными (в котором SSH'евый баннер; я уже не буду
включать показ данных - по отчёту видно, что прибежало 40 байт).
То есть, я бы советовал тебе после готовности к записи сделать getpeername()
и по её ответу понять, что же у нас такое.
Hепонятно, что ты говорил про то, что recv() возвращает 0. Странно это.