Главная страница
    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.46 MB
Время: 0.036 c
15-1201946435
иванз
2008-02-02 13:00
2008.03.09
"многострочный" TLabel


15-1201808527
DrPass
2008-01-31 22:42
2008.03.09
Интересная статистика


3-1193052958
ora-01691
2007-10-22 15:35
2008.03.09
посмотреть свободное место


15-1202120566
asdfa
2008-02-04 13:22
2008.03.09
не могу понять как запускается файл


2-1202994122
Konst5719
2008-02-14 16:02
2008.03.09
Tray (Taskbar Notification Area)





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский