Асинхронные сокеты

uniqueman
Уже с Приветом
Posts: 2013
Joined: 16 Mar 2002 10:01
Location: New York City

Асинхронные сокеты

Post by uniqueman »

При асинхронном режиме работы сокета, если я вызываю функцию connect , то независимо от того доступен ли сервер или нет всегда возвращается true.. Точнее возвращается WSAWOULDBLOCK, но по этой ошибке тоже не скажешь доступен ли сервер или нет, потому что в этом и смысл асинхронной работы..для того чтобы узнать действительно ли доступен сервер, надо что то ему послать. Если send вернет false, значит связи нет..

Можно ли как то узнать еще до вызова send?

спасибо
Sanych
Уже с Приветом
Posts: 7728
Joined: 10 Jan 1999 10:01
Location: OH->TX->MI->MA->VA->FL->...

Post by Sanych »

blocking или nonblocking?
Какая платформа (windows/unix/pocketPC)?
User avatar
Дед Мороз
Уже с Приветом
Posts: 4412
Joined: 06 Nov 2003 17:03
Location: TX

Post by Дед Мороз »

fd_set w;
FD_ZERO(&w); // just in case
FD_SET(socket,&w)

if(select (socket,NULL,&w,NULL,NULL) ==1 )
{

// got it!
}
uniqueman
Уже с Приветом
Posts: 2013
Joined: 16 Mar 2002 10:01
Location: New York City

Post by uniqueman »

blocking или nonblocking?


non blocking..

Какая платформа (windows/unix/pocketPC)?


Win 2000
Sanych
Уже с Приветом
Posts: 7728
Joined: 10 Jan 1999 10:01
Location: OH->TX->MI->MA->VA->FL->...

Post by Sanych »

Дед Мороз, для этого по идее надо сокет заявить неблокирующим. По умолчанию он блокирующий.

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 и так вроде шлепает.
User avatar
Дед Мороз
Уже с Приветом
Posts: 4412
Joined: 06 Nov 2003 17:03
Location: TX

Post by Дед Мороз »

2Sanych: Дык, я изначально понял что сокет не блокирующий (иначе бы и проблемы не было :))

(Тем более что там написано - асинхронный , что есть не блокирующий)
User avatar
A. Fig Lee
Уже с Приветом
Posts: 12072
Joined: 17 Nov 2002 03:41
Location: английская колония

Post by A. Fig Lee »

Дед Мороз wrote:fd_set w;
FD_ZERO(&w); // just in case
FD_SET(socket,&w)

if(select (socket,NULL,&w,NULL,NULL) ==1 )
{

// got it!
}

a connect where?
Верить нельзя никому - даже себе. Мне - можно!
User avatar
Дед Мороз
Уже с Приветом
Posts: 4412
Joined: 06 Nov 2003 17:03
Location: TX

Post by Дед Мороз »

Ессно, до этого ...
User avatar
A. Fig Lee
Уже с Приветом
Posts: 12072
Joined: 17 Nov 2002 03:41
Location: английская колония

Post by A. Fig Lee »

Дед Мороз wrote:Ессно, до этого ...

Ну ему то именно connect нужен! Причем тут select если сервер не доступен?
Верить нельзя никому - даже себе. Мне - можно!
User avatar
roadman
Уже с Приветом
Posts: 707
Joined: 12 Mar 2003 22:29
Location: Moscow->Bay Area, CA

Post by roadman »

Для асинхронных сокетов я использовал IOCompetionPort функции для Windows (CreateIoCompletionPort, GetQueuedCompletionStatus, PostQueuedCompletionStatus)

и aiocb функции для Linux/Unix. (aio_write, aio_read)

По сравнению с Berkley Sockets (1.0) и Windows Socket 2, включая асинхронные сокеты CompletionPort работает намного быстрее.

Однако зачем вам вызывать функцию connect асинхронно (с тайм-аутом ещё понятно зачем, а асинхронно - значит немедленно получить управление в вызываюшем потоке назад)? Все равно до установки соединения Вы не сможете ничего послать... и Вы будете ждать результата функции select, чтобы понять состоялось соединение или нет.
Не проще ли создать отдельный поток и там ждать результата соединения, если надо используя тайм-аут и функцию select.

Return to “Вопросы и новости IT”