"плохой" int connect
От: Evilguc  
Дата: 25.10.08 13:09
Оценка:
Привет всем!
Функция connect в winsocks, в случае, если сервер не сдушает порт или вообще отсутствует, "вешает" программу на секунд 20!!! По-моему это очень много, и поэтому я геморройным способом проверяю весит ли поток, и в случае чего завершаю его:


...
if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) != SOCKET_ERROR) //вот тут обычно происходит "подвешивание"
{
...
}
...





//a тут проверяю сколько времени весит

int CheckIt()
{
    int num = 0;
    while(1)
    {
        Sleep(500);
        if(hash == -999 && num >= 8)
        {
            TerminateThread(hThread, 0);
            return -999;
        }
        if(hash != -999)
        {
            access = 1;
            return hash;
        }
        num++;
    }
    return -13;
}

но вот я считаю, что такой способ не очень рационален да и небезопасен... может кто знает что-нибудь лучше???
Да, кстать, пробовал сдеоать сокет неблокирующим, но в этом случае прога не успевала приконнектиться.
Спасибо!


27.10.08 01:14: Перенесено модератором из 'C/C++. Прикладные вопросы' — Кодт
Re: "плохой" int connect
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 25.10.08 13:14
Оценка:
Здравствуйте, Evilguc, Вы писали:

E>Привет всем!

E>Функция connect в winsocks, в случае, если сервер не сдушает порт или вообще отсутствует, "вешает" программу на секунд 20!!!

Файрволл? Уберите.

E>Да, кстать, пробовал сдеоать сокет неблокирующим, но в этом случае прога не успевала приконнектиться. :xz:


Это Вы плохо документацию читали, мне кажется. Сказали connect(), получили WSAEINPROGRESS и теперь можете спокойно сами ждать сколько нужно и как нужно, проверяя через select() возможность записи. Хотя под виндой часто удобнее воспользоваться асинхронным оповещением.
The God is real, unless declared integer.
Re[2]: "плохой" int connect
От: Evilguc  
Дата: 25.10.08 14:10
Оценка:
Здравствуйте, netch80, Вы писали:

N>Файрволл? Уберите.

нет он здесь нипричем...

N>Это Вы плохо документацию читали, мне кажется.

возможно...

N>Сказали connect(), получили WSAEINPROGRESS и теперь можете спокойно сами ждать сколько нужно и как нужно, проверяя через select() возможность записи.

нет, это я понимаю, но вот проблема в этом и состоит — функция не возвращает никаких значений втечение 20 секунд. Еще так не подумал использовать с неблокирующим сокетом, так что попробую

N>Хотя под виндой часто удобнее воспользоваться асинхронным оповещением.

ну если я все правильно понял, то... мне это не совсем пойдет(по-моему придется слишком сильно перерабатывать код, а тем более если сработает ваше первое предложение, то обойдксь и им)
Re[3]: "плохой" int connect
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 25.10.08 15:21
Оценка:
Здравствуйте, Evilguc, Вы писали:

E>Здравствуйте, netch80, Вы писали:


N>>Файрволл? Уберите.

E>нет он здесь нипричем...

Я подозреваю, что вполне даже "причём" (на серверной стороне). Или же у вас на клиенте что-то относительно старое. Нормальная система без файрволла на коннект на незанятый никем порт тут же отдаст RST и будет облом connect() как только этот RST придёт. Старые винды (района 98 и ранней 2000, AFAIR) были известны тем, что игнорировали RST, потому что сами отдавали его в неуместных случаях (как переполнение слушающей очереди), но сейчас, мне казалось, это уже не актуально. Или актуально? Я бы советовал попробовать пообщаться с каким-нибудь вменяемым юниксом как сервером и посмотреть сниффером, что при этом происходит.

N>>Сказали connect(), получили WSAEINPROGRESS и теперь можете спокойно сами ждать сколько нужно и как нужно, проверяя через select() возможность записи.

E>нет, это я понимаю, но вот проблема в этом и состоит — функция не возвращает никаких значений втечение 20 секунд. Еще так не подумал использовать с неблокирующим сокетом, так что попробую

Я имел в виду как раз работу в неблокирующем режиме. Это в нём, если connect() не состоялся сразу (что возможно только на локальной машине) — возвращается [WSA]EINPROGRESS. В блокирующем, понятно, оно впадёт в ожидание, пока не сработает внутренний таймаут стека.

N>>Хотя под виндой часто удобнее воспользоваться асинхронным оповещением.

E>ну если я все правильно понял, то... мне это не совсем пойдет(по-моему придется слишком сильно перерабатывать код, а тем более если сработает ваше первое предложение, то обойдксь и им)

Тогда действительно включите неблокирующий режим и, если connect() отказался сработать сразу (а это основной вариант), через select() подождать сколько нужно. Ну и всё-таки посмотреть сниффером обмен пакетами.
The God is real, unless declared integer.
Re: "плохой" int connect
От: Pzz Россия https://github.com/alexpevzner
Дата: 25.10.08 15:28
Оценка:
Здравствуйте, Evilguc, Вы писали:

E>Функция connect в winsocks, в случае, если сервер не сдушает порт или вообще отсутствует, "вешает" программу на секунд 20!!! По-моему это очень много, и поэтому я геморройным способом проверяю весит ли поток, и в случае чего завершаю его:


Это ожидаемое поведение. Если с той стороны вообще не отвечают, connect'у нужно сделать достаточное количество попыток, чтобы в этом убедиться. Иначе при не очень хорошей связи connect'ы будут отваливаться слишком рано.

Чтобы программа не засыпала, надо делать неблокирующийся connect, и ожидать его завершения одним из многочисленных методов, доступных в венде.
Re[4]: "плохой" int connect
От: Evilguc  
Дата: 25.10.08 17:15
Оценка:
Здравствуйте, netch80, Вы писали:

N>>>Файрволл? Уберите.

E>>нет он здесь нипричем...

N>Я подозреваю, что вполне даже "причём" (на серверной стороне). Или же у вас на клиенте что-то относительно старое. Нормальная система без файрволла на коннект на незанятый никем порт тут же отдаст RST и будет облом connect() как только этот RST придёт. Старые винды (района 98 и ранней 2000, AFAIR) были известны тем, что игнорировали RST, потому что сами отдавали его в неуместных случаях (как переполнение слушающей очереди), но сейчас, мне казалось, это уже не актуально. Или актуально? Я бы советовал попробовать пообщаться с каким-нибудь вменяемым юниксом как сервером и посмотреть сниффером, что при этом происходит.

нет, с этим я то согласен, но как бы файервол не работал/не работал, все равно такая вот ерунда.


N>Я имел в виду как раз работу в неблокирующем режиме. Это в нём, если connect() не состоялся сразу (что возможно только на локальной машине) — возвращается [WSA]EINPROGRESS. В блокирующем, понятно, оно впадёт в ожидание, пока не сработает внутренний таймаут стека.


хмхм... я вот попробовал, но почему-то возвращает не WSAEINPROGRESS, а WSAEWOULDBLOCK. Конечно скорее всего это с моей стороны ошибка, может поможете:

    BOOL sMode = 1;
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2,2),&wsaData);
    SOCKET sock;
    struct sockaddr_in addr;
    if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) != INVALID_SOCKET)
    {
        addr.sin_family = AF_INET;
        addr.sin_port = htons(SERVER_PORT);
        addr.sin_addr.s_addr = inet_addr(ip);
        int result = ioctlsocket(sock, FIONBIO, (u_long*) &sMode);
        if (result != -1)
        {
               if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) != SOCKET_ERROR)
               {
                           //выполняю обмен данными
               }
        }
        MessageBeep(MB_ICONHAND);
        return WSAGetLastError(); // здесь почему-то возвращается WSAEWOULDBLOCK
    }
    return 0;
Re[5]: "плохой" int connect
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 25.10.08 17:20
Оценка:
Здравствуйте, Evilguc, Вы писали:

E>хмхм... я вот попробовал, но почему-то возвращает не WSAEINPROGRESS, а WSAEWOULDBLOCK. :xz: Конечно скорее всего это с моей стороны ошибка, может поможете:


Посмотрите в документацию. Насколько я могу понять список ошибок, WSAEINPROGRESS остался для версии 1.1, а для 2-й они обобщили WSAEWOULDBLOCK на него. Если так — то WSAEWOULDBLOCK точно так же означает, что соединение начало устанавливаться, но немедленного ответа пока не может быть, и это то, что Вам нужно.
The God is real, unless declared integer.
Re[6]: "плохой" int connect
От: Evilguc  
Дата: 25.10.08 17:52
Оценка:
Здравствуйте, netch80, Вы писали:

N>Посмотрите в документацию. Насколько я могу понять список ошибок, WSAEINPROGRESS остался для версии 1.1, а для 2-й они обобщили WSAEWOULDBLOCK на него. Если так — то WSAEWOULDBLOCK точно так же означает, что соединение начало устанавливаться, но немедленного ответа пока не может быть, и это то, что Вам нужно.


Все спасибо! Вы были правы.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.