Форум: "Сети";
Текущий архив: 2008.03.09;
Скачать: [xml.tar.bz2];
ВнизНеблокирующий Connect() и недоступный узел. Найти похожие ветки
← →
DVM © (2007-06-14 12:18) [0]Столкнулся вот с какой ситуацией. Использую неблокирующие сокеты, точнее неблокирующий Connect():
Как обычно, перевожу сокет в неблокирующий режимBlock := 1;
ioctlsocket(s, FIONBIO, Block)
И начинаю коннект (код примерный, но суть отражает)if Connect(s, FAddr, Len) = SOCKET_ERROR then
begin
if WSAGetLastError = WSAEWOULDBLOCK then
begin
while true do
begin
FD_ZERO(wfd);
FD_SET(s, wfd);
case select(S, nil, @wfd, nil, @TimeVal) of
0: delay(5);
1: if FD_ISSET(s, wfd) then break;
SOCKET_ERROR:
begin
Block := 0;
ioctlsocket(s, FIONBIO, Block);
CloseSocket(s);
end;
end;
end;
end;
end;
Т.е. жду до тех пор, пока сокет не будет готов.
Но вот в чем проблема. Если в момент подключения, т.е. на момент вызова connect() заданный узел был недоступен, то connect все равно возвращает SOCKET_ERROR , а WSAGetLastError = WSAEWOULDBLOCK и я вхожу в цикл, в котором готовности сокета уже не дождаться никогда. Т.е. в этих условиях функция connect() не продолжает фоновой процесс установки соединения. Select всегда возвращает 0 и так бесконечно. Даже если заданный узел вновь станет доступным соединение так и не устанавливается. Хотя по идее должно. Помогает только повторный вызов connect().
Если же на момент вызова connect() узел был доступен, то после нескольких оборотов цикла select возвращает 1 и мы двигаемся дальше. т.е. выходим из цикла.
Это нормальное поведение функции connect()?
← →
Сергей М. © (2007-06-14 13:11) [1]
> Это нормальное поведение функции connect()?
>
Да, нормальное.
Читаем справку к 4-му параметру ф-ции select()
exceptfds:
If connecting (nonblocking), connection attempt failed
Ты этот параметр не используешь, соответственно select() никак не может известить тебя о недоступности узла.
← →
DVM © (2007-06-14 14:43) [2]Изменил так:
if Connect(s, FAddr, Len) = SOCKET_ERROR then
begin
if WSAGetLastError = WSAEWOULDBLOCK then
begin
while true do
begin
FD_ZERO(wfd);
FD_SET(s, wfd);
FD_ZERO(efd);
FD_SET(s, efd);
case select(S, nil, @wfd, @efd, @TimeVal) of
0: delay(5);
1: if FD_ISSET(s, wfd) then
break
else
if FD_ISSET(s, efd) then
begin
// сюда мы никогда не попадаем
end;
SOCKET_ERROR:
begin
Block := 0;
ioctlsocket(s, FIONBIO, Block);
CloseSocket(s);
exit;
end;
end;
end;
end;
end;
Множество efd почему то получается всегда пустым
← →
DVM © (2007-06-14 15:00) [3]Прошу прошения, я стормозил, надо было просто подождать подольше - все ок.
> Сергей М. ©
спасибо.
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2008.03.09;
Скачать: [xml.tar.bz2];
Память: 0.45 MB
Время: 0.047 c