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

Вниз

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

 
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;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.017 c
2-1220626195
D7
2008-09-05 18:49
2008.10.12
Проверить Тип поля


4-1197392650
AngelXXX
2007-12-11 20:04
2008.10.12
Запустить программу с флехи и флеху отключить


2-1220234556
Abcdef123
2008-09-01 06:02
2008.10.12
Как получить подробную информацию об ошибке рантайма?


2-1220523692
Layner
2008-09-04 14:21
2008.10.12
TDBChart - показ множества TLineSeries


2-1220447536
tropik
2008-09-03 17:12
2008.10.12
Как заинсталить компонент в Delphi 2 ?