Так как сокетные события поддерживаются только в WinSock 2, модуль WinSock не содержит объявлений типов и функций, требуемых для их поддержки. Поэтому их придется объявлять самостоятельно. Прежде всего, должен быть объявлен тип дескриптора событий, который в MSDN называется WSAEVENT
. В Delphi он может быть объявлен следующим образом:
PWSAEvent = ^TWSAEvent;
TWSAEvent = THandle;
Событие создается с помощью функции WSACreateEvent
, прототип которой приведен в листинге 2.55.
Листинг 2.55. Функция WSACreateEvent
// ***** Описание на C++ *****
WSAEVENT WSACreateEvent(void);
// ***** Описание на Delphi *****
function WSACreateEvent: TWSAEvent;
Событие, созданное этой функцией, находится в сброшенном состоянии, при ожидании автоматически не сбрасывается, не имеет имени и обладает стандартными атрибутами безопасности. В MSDN отмечено, что сокетное событие на самом деле является простым системным событием, и его можно создавать с помощью стандартной функции CreateEvent
, управляя значениями всех перечисленных параметров.
Функция создает событие и возвращает его дескриптор. Если произошла ошибка, функция возвращает значение WSA_INVALID_EVENT
(0). Для ручного взведения и сброса события предназначены функции WSASetEvent
и WSAResetEvent
соответственно, прототипы которых приведены в листинге 2.56.
Листинг 2.56. Функции для управления событиями
// ***** Описание на C++ *****
BOOL WSASetEvent(WSAEVENT hEvent);
BOOL WSAResetEvent(WSAEVENT hEvent);
// ***** Описание на Delphi *****
function WSASetEvent(hEvent: TWSAEvent): BOOL;
function WSAResetEvent(hEvent: TWSAEvent): BOOL;
Функции возвращают True
, если операция прошла успешно, и False
— в противном случае.
После завершения работы с событием оно уничтожается с помощью функции WSACloseEvent
(листинг 2.57).
Листинг 2.57. Функция WSACloseEvent
// ***** Описание на C++ *****
BOOL WSACloseEvent(WSAEVENT nEvent);
// ***** Описание на Delphi *****
function WSACloseEvent(hEvent: TWSAEvent): BOOL;
Функция уничтожает событие и освобождает связанные с ним ресурсы. Дескриптор, переданный в качестве параметра, становится недействительным. Для ожидания взведения событий служит функция WSAWaitForMultiрleEvents
(листинг 2.58).
Листинг 2.58. Функция WSAWaitForMultipleEvents
// ***** Описание на C++ *****
DWORD WSAWaitForMultipleEvents(DWORD cEvents, const WSAEVENT FAR *lphEvents, BOOL fWaitAll, WORD dwTimeout, BOOL fAlertable);
// ***** Описание на Delphi *****
function WSAWaitForMultipleEvents(cEvents: DWORD; lphEvents: PWSAEvent; fWaitAll: BOOL; dwTimeout: DWORD; fAlertable: BOOL): DWORD;
Дескрипторы событий, взведения которых ожидает нить, должны храниться в массиве, размер которого передаётся через параметр cEvents
, а указатель — через параметр lphEvents
. Параметр fWaitAll
определяет, что является условием окончания ожидания: если он равен True
, ожидание завершается, когда все события из переданного массива оказываются во взведенном состоянии, если False
— когда оказывается взведенным хотя бы одно из них. Параметр dwTimeout
определяет тайм-аут ожидания в миллисекундах. В WinSock 2 определена константа WSA_INFINITE
(совпадающая по значению со стандартно константой INFINITE
), которая задает бесконечное ожидание. Параметр fAlertable
нужен при перекрытом вводе-выводе: мы рассмотрим его позже в разд. 2.2.9 . Если перекрытый ввод-вывод не используется, fAlertable
должен быть равен False
.
Существует ограничение на число событий, которое можно ожидать с помощью данной функции. Максимальное число событий определяется константой WSA_MAXIMUM_WAIT_EVENTS
, которая в данной реализации равна 64.
Результат, возвращаемый функцией, позволяет определить, по каким причинам закончилось ожидание. Если ожидалось взведение всех событий ( fWaitAll = True
), и оно произошло, функция возвращает WSA_WAIT_EVENT_0
(0). Если ожидалось взведение хотя бы одного из событий, возвращается WSA_WAIT_EVENT_0 + Index
, где Index
— индекс взведенного события в массиве lphEvents
(отсчет индексов начинается с нуля). Если ожидание завершилось по тайм-ауту, возвращается значение WSA_WAIT_TIMEOUT
(258). И наконец, если произошла какая-либо ошибка, функция возвращает WSA_WAIT_FAILED
( $FFFFFFFF
).
Существует еще одно значение, которое может возвратить функция WSAWaitForMultipleEvents
: WAIT_IO_COMPLETION
(это константа из стандартной части Windows API, она объявлена в модуле Windows
). Смысл этого результата и условия, при которых он может быть возвращен, мы рассмотрим в разд. 2.2.9 .
Функции, которые мы рассматривали до сих пор, являются аналогами системных функций для стандартных событий. Теперь мы переходим к рассмотрению тех функций, которые отличают сокетные события от стандартных. Главная из них — WSAEventSelect
, позволяющая привязать события, создаваемые с помощью WSACreateEvent
, к тем событиям, которые происходят на сокете. Прототип этой функции приведен в листинге 2.59.
Читать дальше
Конец ознакомительного отрывка
Купить книгу