При асинхронном режиме работы сокета, если я вызываю функцию connect , то независимо от того доступен ли сервер или нет всегда возвращается true.. Точнее возвращается WSAWOULDBLOCK, но по этой ошибке тоже не скажешь доступен ли сервер или нет, потому что в этом и смысл асинхронной работы..для того чтобы узнать действительно ли доступен сервер, надо что то ему послать. Если send вернет false, значит связи нет..
Можно ли как то узнать еще до вызова send?
спасибо
Асинхронные сокеты
-
- Уже с Приветом
- Posts: 2013
- Joined: 16 Mar 2002 10:01
- Location: New York City
-
- Уже с Приветом
- Posts: 7728
- Joined: 10 Jan 1999 10:01
- Location: OH->TX->MI->MA->VA->FL->...
-
- Уже с Приветом
- Posts: 4412
- Joined: 06 Nov 2003 17:03
- Location: TX
-
- Уже с Приветом
- Posts: 2013
- Joined: 16 Mar 2002 10:01
- Location: New York City
-
- Уже с Приветом
- Posts: 7728
- Joined: 10 Jan 1999 10:01
- Location: OH->TX->MI->MA->VA->FL->...
Дед Мороз, для этого по идее надо сокет заявить неблокирующим. По умолчанию он блокирующий.
fd_set sock2control, sock2fail;
unsigned long blockingOption = 1; // неблокирующий сокет
int i = 0;
struct timeval tmout;
tmout.tv_sec = 5; // 5 секунд таймаут
tmout.tv_usec = 0;
FD_ZERO(&sock2control); // init sockets control list
FD_ZERO(&sock2fail);
FD_SET(socket, &sock2control); // set the socket to control lists
FD_SET(socket, &sock2fail);
ioctlsocket (socket, FIONBIO, &blockingOption); // разблокировать
i = connect (socket, (SOCKADDR *) &socket2connect, sizeof(socket2connect));
if (select(NULL, &sock2fail, &sock2control, &tmout) == 1)
{
if (FD_ISSET(m_hSocket, &sock2control))
{
// коннекшена не вышло, сорри
}
else
{
// законнектились успешно, можно разблокировать сокет если надо
// типа blockingOption = 0; ioctlsocket (socket, FIONBIO, &blockingOption);
}
}
Схема надежно работает под Windows CE 3.0 и Pocket PC 2xxx, под обычной виндой не помню, под линухом этот код не пробовал.
Под виндой еще рекомендуется
WSADATA WSAData;
WSAStartup (MAKEWORD(1,1), &WSAData);
........................
// упражнения в издевательствах над сокетами
........................
WSACleanup( );
хотя под CE/PPC2xxx и так вроде шлепает.
fd_set sock2control, sock2fail;
unsigned long blockingOption = 1; // неблокирующий сокет
int i = 0;
struct timeval tmout;
tmout.tv_sec = 5; // 5 секунд таймаут
tmout.tv_usec = 0;
FD_ZERO(&sock2control); // init sockets control list
FD_ZERO(&sock2fail);
FD_SET(socket, &sock2control); // set the socket to control lists
FD_SET(socket, &sock2fail);
ioctlsocket (socket, FIONBIO, &blockingOption); // разблокировать
i = connect (socket, (SOCKADDR *) &socket2connect, sizeof(socket2connect));
if (select(NULL, &sock2fail, &sock2control, &tmout) == 1)
{
if (FD_ISSET(m_hSocket, &sock2control))
{
// коннекшена не вышло, сорри
}
else
{
// законнектились успешно, можно разблокировать сокет если надо
// типа blockingOption = 0; ioctlsocket (socket, FIONBIO, &blockingOption);
}
}
Схема надежно работает под Windows CE 3.0 и Pocket PC 2xxx, под обычной виндой не помню, под линухом этот код не пробовал.
Под виндой еще рекомендуется
WSADATA WSAData;
WSAStartup (MAKEWORD(1,1), &WSAData);
........................
// упражнения в издевательствах над сокетами
........................
WSACleanup( );
хотя под CE/PPC2xxx и так вроде шлепает.
-
- Уже с Приветом
- Posts: 4412
- Joined: 06 Nov 2003 17:03
- Location: TX
-
- Уже с Приветом
- Posts: 12072
- Joined: 17 Nov 2002 03:41
- Location: английская колония
-
- Уже с Приветом
- Posts: 12072
- Joined: 17 Nov 2002 03:41
- Location: английская колония
-
- Уже с Приветом
- Posts: 707
- Joined: 12 Mar 2003 22:29
- Location: Moscow->Bay Area, CA
Для асинхронных сокетов я использовал IOCompetionPort функции для Windows (CreateIoCompletionPort, GetQueuedCompletionStatus, PostQueuedCompletionStatus)
и aiocb функции для Linux/Unix. (aio_write, aio_read)
По сравнению с Berkley Sockets (1.0) и Windows Socket 2, включая асинхронные сокеты CompletionPort работает намного быстрее.
Однако зачем вам вызывать функцию connect асинхронно (с тайм-аутом ещё понятно зачем, а асинхронно - значит немедленно получить управление в вызываюшем потоке назад)? Все равно до установки соединения Вы не сможете ничего послать... и Вы будете ждать результата функции select, чтобы понять состоялось соединение или нет.
Не проще ли создать отдельный поток и там ждать результата соединения, если надо используя тайм-аут и функцию select.
и aiocb функции для Linux/Unix. (aio_write, aio_read)
По сравнению с Berkley Sockets (1.0) и Windows Socket 2, включая асинхронные сокеты CompletionPort работает намного быстрее.
Однако зачем вам вызывать функцию connect асинхронно (с тайм-аутом ещё понятно зачем, а асинхронно - значит немедленно получить управление в вызываюшем потоке назад)? Все равно до установки соединения Вы не сможете ничего послать... и Вы будете ждать результата функции select, чтобы понять состоялось соединение или нет.
Не проще ли создать отдельный поток и там ждать результата соединения, если надо используя тайм-аут и функцию select.