Соединение с сервером через винсок

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Sifon110, 3 Feb 2013.

  1. Sifon110

    Sifon110 New Member

    Joined:
    13 Mar 2011
    Messages:
    34
    Likes Received:
    1
    Reputations:
    0
    Соединяюсь с сокетом через функцию Connect
    Если сервер не отвечает, то есть не удалось к нему подключится, через некоторое время (причем почему-то все время разное, в промежутке 20-120сек) функция возвращает код ошибки.

    Собственно вопрос: Возможно ли как-то указать свое время соединения, после истечении которого произошел бы выход из функции Connect?

    Яп: дельфи.
     
    #1 Sifon110, 3 Feb 2013
    Last edited: 3 Feb 2013
  2. ourcode

    ourcode New Member

    Joined:
    2 Feb 2013
    Messages:
    21
    Likes Received:
    4
    Reputations:
    5
    Неплохо было бы указать язык программирования, который ты используешь.

    Как правило можно всегда, задается в одном из следующих мест:
    1. конфигурационный файл (значение по умолчанию), для скриптовых языков
    2. параметры, опции сокета
    3. необязательный параметр в функции (методе) connect
     
  3. Eich3

    Eich3 Member

    Joined:
    27 Jan 2013
    Messages:
    22
    Likes Received:
    7
    Reputations:
    5
    AFAIK в API сокетов нет опций именно для таймаута на connect (есть таймауты на send и recv, но утверждений что оно распространяется и на connect не дается).

    Более-менее надежное решение проблемы под windows

    1. Создать сокет
    2. Создать дескриптор для события, через который мы узнаем о завершении операции connect (создается вызовом WSACreateEvent)
    3. Использовать WSAEventSelect для привязки созданного дескриптора к сокету, на отслеживание FD_CONNECT
    4. Забиндить сокет и перевести его в неблокирующий режим (делается через ioctlsocket)
    5. Инициировать connect и проверить, что оно вернуло WSAEWOULDBLOCK.
    6. Вызвать WaitForSingleObject с ранее созданным событием и задать там таймаут. Должно вернуть WAIT_OBJECT_0 в случае возбуждения события и WAIT_TIMEOUT в случае истечения времени.

    Далее закрыть дескриптор события и перевести сокет обратно в блокирующий режим, если нужно.

    Еще можно вместо событий вызывать select, там тоже есть возможность задать таймаут на готовность к чтению/записи.
     
    1 person likes this.
  4. Sifon110

    Sifon110 New Member

    Joined:
    13 Mar 2011
    Messages:
    34
    Likes Received:
    1
    Reputations:
    0
    У меня получился такой код:

    Code:
    var
     hEvent: Thandle;
     s:Tsocket;
     addr: Tsockaddr;
     Sock: TWSAData;
     block:boolean;
     s1,s2:string;
     Reason:DWORD;
    begin
     WSAStartup(MAKEWORD(2,2),sock);
     hEvent:=WSACreateEvent();
     WSAEventSelect(s, hEvent, FD_CONNECT);
     s:=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
     FillChar(addr, SizeOf(sockaddr_in), 0);
     addr.sin_family:=AF_Inet;
     addr.sin_port:=htons(80);
     addr.sin_addr.S_addr:=inet_addr(Pchar('77.88.21.3'));
     bind(s, addr, SizeOf(TSockAddrin));
     block:=true;
     ioctlsocket(s, FIONBIO, cardinal(block));
     Reason:=WaitForSingleObject(hEvent, 1000);
     if Reason = WAIT_TIMEOUT then
      showmessage('no connect');
     if Reason = WAIT_OBJECT_0 then
      showmessage('connect');
    
    Ошибка на строке bind(s, addr, SizeOf(TSockAddrin)); :
    Incompatible types: 'TSockAddrIn' and 'PSockAddr'

    Если поменять addr: Tsockaddr; на addr: Зsockaddr; - компилируется, но при выполнении Крит. ошибка доступа к области памяти на строке addr.sin_family:=AF_Inet;

    Подскажите, как исправить эту проблему.
     
  5. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    936
    Likes Received:
    162
    Reputations:
    27
    Может быть нужно сначала создать сокет, а уже потом привязывать к нему событие? Именно так написали постом выше.
    У твоем коде вместо bind должен быть connect.
    Получить PSockAddr (указатель на TSockAddr) можно так: @addr.
    Здесь в событиях нет нужды, лучше select использовать.
     
  6. Sifon110

    Sifon110 New Member

    Joined:
    13 Mar 2011
    Messages:
    34
    Likes Received:
    1
    Reputations:
    0
    Спасибо, получилось. :cool: