Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2008.10.12;
Скачать: [xml.tar.bz2];

Вниз

Время ожидания коннекта сокетом при недоступной сети   Найти похожие ветки 

 
SpellCaster   (2007-11-06 13:32) [0]

Всем привет!
Есть небольшая трабла: если соединение с сетью неактивно или отключено, то попытка соединиться через него затягивается секунд на 10-15, что слишком уж долго. Сокет создаётя с таймаутом 5000, то есть по идее должен вываливаться гораздо раньше. Может, где-то в недрах WinSock-а есть некая глобальная переменная? У кого-нибудь есть идеи?


 
Сергей М. ©   (2007-11-06 13:43) [1]

Похоже ты путаешь лукап с коннектом


 
DVM ©   (2007-11-06 16:01) [2]


> SpellCaster

ждет на функции Connect() ? Если да, то используй неблокирующие сокеты или хотя бы неблокирующий Connect.


 
DVM ©   (2007-11-06 16:02) [3]


> Сокет создаётя с таймаутом 5000

Что за сокет ты создаешь? (Компонент или сам). И где ты указал таймаут?


 
SpellCaster   (2007-11-06 16:40) [4]

> Сергей М.

Да нет вроде

> DVM

Ага, на ней. Неблоки не хочется, а неблок. коннект нет смысла, т.к. сокет в отдельном треде.

> Что за сокет ты создаешь? (Компонент или сам).

Свой класс, простая обёртка над АПИ. Блокирующий сокет, вот кусок кода его создания:

fSckt:=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if fSckt=INVALID_SOCKET then Exit;
if bind(fSckt,fLocalAddr,SizeOf(TSockAddr))=SOCKET_ERROR then Exit;
fInTraf:=0; fOutTraf:=0;
Result:=WinSock.connect(fSckt,tmp_addr,SizeOf(TSockAddr));
if Result=SOCKET_ERROR then Exit;


> И где ты указал таймаут?

Мда, сейчас посмотрел, там у меня таймаут используется только при проверке готовности, т.е. в коннекте он не участвует. Интересно, его вообще можно поменять?


 
DVM ©   (2007-11-06 17:01) [5]


> а неблок. коннект нет смысла, т.к. сокет в отдельном треде.

Смысл есть, т.к. даже если все помещено в отдельный поток, ты завершения потока не дождешься, пока Connect() не отработает. Имеет смысл переводить сокет перед выполнением Connect() в неблокирующий режим, а после возвращать в блокирующий как более простой для работы. Сам Connect() никаким образом не прервать, не помогает ни закрытие сокета из другого потока, ни что другое.


> Интересно, его вообще можно поменять?

Можно. Я вот так делал с неблокирующим режимом (можно и с блокирующим, но с неблок лучше - можно мгновенно прервать коннект)


function THTTPInputThread.SocketConnect: integer;
var
 NoBlock: integer;
 Wfd, EFd: TFDSet;
 TimeVal: TTimeVal;
begin
 Result := socket(AF_INET, SOCK_STREAM, 0);
 if Result = INVALID_SOCKET then
   begin
     Result := -1;
     exit;
   end;

 NoBlock := 1;
 if ioctlsocket(Result, FIONBIO, NoBlock) = SOCKET_ERROR then
   begin
     CloseSocket(Result);
     Result := -1;
     exit;
   end;

 if Connect(Result, FAddr, SizeOf(FAddr)) = SOCKET_ERROR then
   begin
     if WSAGetLastError =  WSAEWOULDBLOCK then
       begin
         while not Terminated do
           begin
             FD_ZERO(wfd);
             FD_SET(result, wfd);

             FD_ZERO(efd);
             FD_SET(result, efd);

             TimeVal.tv_sec := 0;
             TimeVal.tv_usec := 50;

             case select(0, nil, @wfd, @efd, @TimeVal) of
               0: sleep(50);
               1: if FD_ISSET(Result, wfd) then
                    break
                  else
                    if FD_ISSET(Result, efd) then
                      begin
                        NoBlock := 0;
                        ioctlsocket(Result, FIONBIO, NoBlock);
                        CloseSocket(Result);
                        Result := -1;
                        exit;
                      end;
               SOCKET_ERROR:
                 begin
                   NoBlock := 0;
                   ioctlsocket(Result, FIONBIO, NoBlock);
                   CloseSocket(Result);
                   Result := -1;
                   exit
                 end;
             end;
           end;
        end
      else
        begin
          NoBlock := 0;
          ioctlsocket(Result, FIONBIO, NoBlock);
          CloseSocket(Result);
          Result := -1;
        end;
   end;

 //Возврат в блокирующий режим
 NoBlock := 0;
 if ioctlsocket(Result, FIONBIO, NoBlock) = SOCKET_ERROR then
   begin
     CloseSocket(Result);
     Result := -1;
   end;
end;


 
SpellCaster   (2007-11-06 17:17) [6]

> Смысл есть, т.к. даже если все помещено в отдельный поток,
> ты завершения потока не дождешься, пока Connect() не отработает.

Логично! Ты прав!
Пример сейчас поковыряю, а пока еще вопрос:

> можно и с блокирующим, но с неблок лучше - можно мгновенно
> прервать коннект

Как с блокирующими сделать?


 
SpellCaster   (2007-11-06 17:37) [7]

Кстати, "Result := -1;" легче присвоить в начале функции, а при ошибке просто выходить - сэкономит несколько строчек )).



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2008.10.12;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.054 c
15-1218782666
MBo
2008-08-15 10:44
2008.10.12
Анонимные методы в будущем Тибуроне


1-1199816989
Wolf
2008-01-08 21:29
2008.10.12
Как установить лимит по времени на некую процедуру ?


2-1220529187
KirillRepin
2008-09-04 15:53
2008.10.12
помогите с DBComboBox


2-1220073543
DarkLord
2008-08-30 09:19
2008.10.12
Имитация DblClick


15-1219248023
sqler
2008-08-20 20:00
2008.10.12
простой SQL запрос





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский