Программирование на C++ глазами хакера

   тефаль йогуртница отзывы, творог. |       

Асинхронная работа через объект события


Если в программе нет процедуры обработки сообщений, то можно воспользоваться объектами событий. В этом случае алгоритм работы будет несколько иной:

Создать объект события с помощью функции WSACreateEvent.

Выбрать сокет с помощью функции WSAEventSelect.

Ожидать событие с помощью функции WSAWaitForMultipleEvents.

Давайте подробно рассмотрим все функции, необходимые для работы с объектами событий.

Первым делом следует создать событие с помощью функции WSACreateEvent. Функции не надо передавать никаких параметров, она просто возвращает новое событие типа WSAEVENT:

WSAEVENT WSACreateEvent(void);

Теперь нужно связать сокет с этим объектом и указать события, которые нам нужны. Для этого используется функция WSAEventSelect:

int WSAEventSelect ( SOCKET s, WSAEVENT hEventObject, long lNetworkEvents )

Первый параметр — это сокет, события которого нас интересуют. Второй параметр — объект события. Последний параметр — это необходимые события. В качестве последнего параметра можно указывать те же константы, что рассматривались для функции WSAAsyncSelect (все они начинаются с префикса FD_).

Раньше вы уже встречались с функциями WaitForSingleObject и WaitForMultipleObjects, которые ожидают наступления события типа HANDLE. Для сетевых событий используется похожая функция с именем WSAWaitForMultipleEvents:

DWORD WSAWaitForMultipleEvents ( DWORD cEvents, const WSAEVENT FAR *lphEvents, BOOL fWaitAll, DWORD dwTimeOUT, BOOL fAlertable );

Давайте рассмотрим каждый параметр:

cEvents — количество объектов событий, изменение состояния которых нужно ожидать. Чтобы узнать максимальное число, воспользуйтесь константой WSA_MAXIMUM_WAIT_EVENTS;

lphEvents — массив объектов событий, которые нужно ожидать;

fWaitAll — режим ожидания событий. Если указано TRUE, то функция ожидает, пока все события не сработают, иначе — после первого передает управление программе;



dwTimeOUT — временной интервал в миллисекундах, в течение которого нужно ожидать события. Если в этом временном интервале не возникло события, то функция возвращает значение WSA_WAIT_TIMEOUT. Если нужно ожидать бесконечно, то можно указать константу WSA_INFINITE;


fAlertable — параметр используется при перекрестном вводе/выводе, который я не рассматриваю в этой книге, поэтому указан FALSE.

Чтобы узнать, какое событие из массива событий сработало, нужно вычесть из возвращенного функцией WSAWaitForMultipleEvents значения константу WSA_WAIT_EVENT_0.

Прежде чем вызывать функцию WSAWaitForMultipieEvents, все события в массиве должны быть пустыми. Если хотя бы одно из них будет занято, то функция сразу вернет управление программе, и не будет ожидания. После выполнения функции отработавшие события становятся занятыми, и после обработки их надо освободить. Для этого используется функция WSAResetEvent:

BOOL WSAResetEvent ( WSAEVENT hEvent );

Функция очищает состояние события, указанного в качестве единственного параметра.

Когда событие уже не нужно, его необходимо закрыть. Для этого используется функция WSACloseEvent. Функции следует передать объект события, который необходимо закрыть:

BOOL WSACloseEvent ( WSAEVENT hEvent );

Если закрытие прошло успешно, то функция возвращает TRUE, иначе — FALSE.


Содержание раздела