Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
ВнизDisconnectEx - как использовать? Найти похожие ветки
← →
ProgRAMmer Dimonych © (2012-08-02 12:20) [0]Программа многократно обращается по TCP к одним и тем же узлам сети: соединились, отправили блок запрос, получили ответ, закрыли соединение. Поставлена задача: не пересоздавать сокет при каждом обращении, а использовать один и тот же. Для этих целей, если верить гуглу и MSDN, предназначена DisconnectEx().
Попытка задействовать DisconnectEx() показала, что вместе с ней обычный connect() не прокатит и надо использовать ConnectEx(). Произведя замену, получаю код ошибки 10022 - WSAEINVAL, что в случае с ConnectEx() означает, что сокет не привязан. Делаю bind() на INADDR_ANY с нулевым портом - получаю при попытке чтения/записи из/в сокет 10057, 10048 или 10038.
Может ли кто-нибудь поделиться отсутствующим в MSDN примером правильного использования ConnectEx() и DisconnectEx() в связке? Или хотя бы рассказать о подводных камнях?int CWSMonitor::ConnectWithTimeout(SOCKET s, WSAEVENT hConnectEvent, SOCKADDR *name, int namelen, DWORD Timeout)
{
int Result = 0;
while (TRUE)
{
OVERLAPPED Overlapped;
ZeroMemory(&Overlapped, sizeof(Overlapped));
Overlapped.hEvent = hConnectEvent;
ResetEvent(hConnectEvent);
SOCKADDR_STORAGE sa_temp;
ZeroMemory(&sa_temp, sizeof(sa_temp));
sa_temp.ss_family = name->sa_family;
switch (name->sa_family)
{
case AF_INET:
((LPSOCKADDR_IN)&sa_temp)->sin_addr.S_un.S_addr = INADDR_ANY;
break;
case AF_INET6:
((LPSOCKADDR_IN6)&sa_temp)->sin6_addr = in6addr_any;
break;
}
bind(s, (LPSOCKADDR)&sa_temp, sizeof(sa_temp));
if (FALSE == ConnectEx(s, name, namelen, NULL, 0, NULL, &Overlapped))
{
Result = WSAGetLastError();
if (WSA_IO_PENDING != Result)
break;
}
setsockopt(s, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0);
DWORD dwTransfer, dwFlags;
if (FALSE == WSAGetOverlappedResult(s, &Overlapped, &dwTransfer, TRUE, &dwFlags))
{
Result = WSAGetLastError();
break;
}
Result = ERR_GOODRET;
break;
}
return Result;
}
← →
Rouse_ © (2012-08-02 19:53) [1]TIME_WAIT учитываешь в 240 секунд перед повторным использованием?
← →
ProgRAMmer Dimonych © (2012-08-02 20:44) [2]> [1] Rouse_ © (02.08.12 19:53)
> TIME_WAIT учитываешь в 240 секунд перед повторным использованием?
М-м-м, да, на тестовом уже увидел. У меня, правда, в реестре на 30 секунд прописано, но дело, похоже, именно в нём. Пришлось отказаться от глупой затеи: запросы идут действительно очень часто.
← →
Rouse_ © (2012-08-02 20:53) [3]Затея действительно странная, я просто не вижу выигрыша от того что сокет не будет пересоздаваться. Только усложнение кода программы.
← →
ProgRAMmer Dimonych © (2012-08-02 21:00) [4]> [3] Rouse_ © (02.08.12 20:53)
Вышестоящие особы хотели сэкономить время на создании сокета. Не на подключении :)
← →
Rouse_ © (2012-08-02 21:03) [5]
> ProgRAMmer Dimonych © (02.08.12 21:00) [4]
> > [3] Rouse_ © (02.08.12 20:53)
>
> Вышестоящие особы хотели сэкономить время на создании сокета.
> Не на подключении :)
Да ну брось, он у тебя час чтоль создается? :)
Ты наоборот по времени проиграл, т.к. исполнение этого кода (даже если бы он работал) более продолжительное, чем время затрачиваемое на создание сокета :)
← →
ProgRAMmer Dimonych © (2012-08-02 21:04) [6]Вообще, кстати, интересный вопрос тогда: а смысл в DisconnectEx()? Ладно если бы, как они пишут в MSDN:
The interval of time that must elapse before TCP can release a closed connection and reuse its resources is known as the TIME_WAIT state or the 2MSL state. During this time, the connection can be reopened at much less cost to the client and server than establishing a new connection.
... и можно было соединиться "at much less cost". А так?
← →
ProgRAMmer Dimonych © (2012-08-02 21:05) [7]> [5] Rouse_ © (02.08.12 21:03)
Лично меня намного больше беспокоила скорость завершения потоков, которые эти запросы шлют: если соединение медленное, там бывало до десятка секунд требовалось.
← →
ProgRAMmer Dimonych © (2012-08-02 21:06) [8]P.S. Но это к теме не имеет никакого отношения
← →
Rouse_ © (2012-08-02 21:06) [9]Смысл в том что повторное соединение с теми-же параметрами (тот-же адрес и порт) происходит гораздо меньшими усилиями, т.к. в данный момент соединение реально еще не разорвано...
← →
ProgRAMmer Dimonych © (2012-08-02 21:09) [10]> [9] Rouse_ © (02.08.12 21:06)
> Смысл в том что повторное соединение с теми-же параметрами
> (тот-же адрес и порт) происходит гораздо меньшими усилиями,
> т.к. в данный момент соединение реально еще не разорвано...
Но ведь 240 секунд же до следующего успешного подключения. Или я туплю и речь идёт о том, чтобы привязать клиентский сокет к конкретным локальному адресу и порту?
← →
Rouse_ © (2012-08-02 21:11) [11]
> Но ведь 240 секунд же до следующего успешного подключения
Нет, это в случае реюза, т.е. сначала стукнулся например на 127,0,0,1 а потом захотел на 192,168,0,10 - то сиди и жди. А если обратно на локалхост то сразу получишь на руки валидный описатель.
← →
ProgRAMmer Dimonych © (2012-08-02 21:24) [12]> [11] Rouse_ © (02.08.12 21:11)
>
> > Но ведь 240 секунд же до следующего успешного подключения
>
> Нет, это в случае реюза, т.е. сначала стукнулся например
> на 127,0,0,1 а потом захотел на 192,168,0,10 - то сиди и
> жди. А если обратно на локалхост то сразу получишь на руки
> валидный описатель.
Но у меня именно такая ситуация и была: и в проекте, и в тестовом приложении. На локалхост, на один и тот же порт. Может быть, я всё-таки чего-нибудь недокрутил с опциями сокета, например?
← →
Rouse_ © (2012-08-02 21:29) [13]Тут целиком проект смотреть нужно, по приведенному куску кода сложно сказать.
Накидай минимальную демку клиента и сервера, там и "будем посмотреть" :)
← →
Rouse_ © (2012-08-02 21:33) [14]Зы, ну и причеши код, раз уж на сях пишешь, а то:
if (FALSE == ConnectEx
if (FALSE == WSAGetOverlappedResult
Result = WSAGetLastError();
break;
← →
ProgRAMmer Dimonych © (2012-08-02 21:41) [15]> [13] Rouse_ © (02.08.12 21:29)
Вот моё тестовое для клиента: http://pastebin.com/YNKehGJM
Сервером у меня было приложение, которое висит на том же компе и слушает TCP-порт 5556.
Логика работы сервера: прочитать из сокета запрос, отправить ответ и сразу закрыть сокет. Тестовое приложение ничего не отправляет, так что сервер вряд ли...
Хотя стоп! Я правильно понимаю: сервер тоже не должен вызывать closesocket()? А с другой стороны closesocket() ведь максимум хэндл ему освободит.
В общем, тестовое у меня выдает 10022 и/или 10048, пока не сделаю интервал побольше.
← →
ProgRAMmer Dimonych © (2012-08-02 21:43) [16]> [14] Rouse_ © (02.08.12 21:33)
Причёсывание большого смысла не имеет: всё равно заставят обратно под общий стиль проекта чесать. Если бы на Delphi - там я ещё сам себе хозяин с большего.
← →
Rouse_ © (2012-08-02 21:54) [17]
> ProgRAMmer Dimonych © (02.08.12 21:41) [15]
Ок, завтра с работы гляну как завал разгребу... ближе ко второй половине дня.
> всё равно заставят обратно под общий стиль проекта чесать.
Не понял, данные функции возвращают BOOL и работать с ними нужно как с BOOL, т.е. if (!ConnectEx и т.п. ну и return обычно используется не на выходе из функции а по факту. Нафига тянуть результат к концу функции, когда выйти можно уже сейчас с указанием результата?
← →
Rouse_ © (2012-08-02 21:55) [18]зы, ну это я уж не говорю про избыточное while (TRUE) :)
← →
ProgRAMmer Dimonych © (2012-08-02 22:03) [19]> [17] Rouse_ © (02.08.12 21:54)
> Не понял, данные функции возвращают BOOL и работать с ними
> нужно как с BOOL, т.е. if (!ConnectEx и т.п.
Здесь аргументация типа "А вдруг тип возвращаемого значения изменится? А APIшные - за компанию. И вообще: BOOL и bool - это разные типы". Отчасти правы, конечно, да и возбухать лишний раз не хоцца.
> ну и return
> обычно используется не на выходе из функции а по факту.
> Нафига тянуть результат к концу функции, когда выйти можно
> уже сейчас с указанием результата?
> зы, ну это я уж не говорю про избыточное while (TRUE) :)
Это вот такой модный способ не делать goto и не использовать исключения при обработке ошибок. Код защитный, а у них в былые времена исключения под защитой криво работали. Груз истории :)
← →
Rouse_ © (2012-08-02 22:07) [20]
> и не использовать исключения при обработке ошибок
Ааа, понятно, да вирталочки не любят обработку исключений :)
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.07 c