Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.03.09;
Скачать: CL | DM;

Вниз

Неблокирующий 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;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.012 c
2-1202755883
1иван
2008-02-11 21:51
2008.03.09
TMemoryStream + dll


2-1202826365
smartleds
2008-02-12 17:26
2008.03.09
Народ , подскажите как мне можно узнать значение сигнала


2-1202894259
Washington
2008-02-13 12:17
2008.03.09
Двойной щелчок по "чексу" в CheckListBox e


2-1202718597
Петр
2008-02-11 11:29
2008.03.09
timer+forma


15-1201902190
Kostafey
2008-02-02 00:43
2008.03.09
С днем рождения ! 2 февраля