Чтение онлайн

на главную

Жанры

О чём не пишут в книгах по Delphi

Григорьев Антон Борисович

Шрифт:
Листинг 2.70. Функция
WSAGetOverlappedResult

// ***** Описание на C++ *****

BOOL WSAGetOverlappedResult(SOCKET s, LPWSAOVERLAPРED lpOverlapped, LPDWORD lpcbTransfer, BOOL fWait, LPDWORD lpdwFlags);

// ***** Описание на Delphi *****

function WSAGetOverlappedResult(S: TSocket; lpOverlapped: PWSAOverlapped; var cbTransfer: DWORD; fWait: BOOL; var Flags: DWORD): BOOL;

Параметры 

S
и
lpOverlapped
функции
WSAGetOverlappedResult
определяют coкет
и операцию перекрытого ввода-вывода, информацию о которой требуется получить. Их значения должны совпадать со значениями соответствующих параметров, переданных функции
WSARecv
. Через параметр
cbTransfer
возвращается число полученных байтов, а через параметр
Flags
— флаги (напомним, что в случае TCP и UDP флаги не модифицируются, и выходное значение параметра
Flags
будет равно входному значению параметра
Flags
функции
WSARecv
).

Допускается вызов функции

WSAGetOverlappedResult
до того, как операция перекрытого ввода-вывода будет завершена. В этом случае поведение функции зависит от параметра
fWait
. Если он равен
True
, функция переводит нить в состояние ожидания до тех пор, пока операция не будет завершена. Если он равен
False
, функция завершается немедленно с ошибкой
WSA_IO_INCOMPLETE
(996).

Функция

WSAGetOverlappedResult
возвращает
True
, если операция перекрытого ввода-вывода успешно завершена, и
False
, если произошли какие-то ошибки. Ошибка может возникнуть в одном из трех случаев:

1. Операция перекрытого ввода-вывода еще не завершена, а параметр

fWait
равен
False
.

2. Операция перекрытого ввода-вывода завершилась с ошибкой (например, из-за разрыва связи).

3. Параметры, переданные функции

WSAGetOverlappedResult
, имеют некорректные значения.

Точную причину, по которой функция вернула

False
, можно установить стандартным образом — по коду ошибки, возвращаемому функцией
WSAGetLastError
.

В принципе, программа может вообще не использовать события для отслеживания завершения операции ввода-вывода, а вызывать вместо этого время от времени функцию

WSAGetOverlappedResult
в удобные для себя моменты. Тогда при вызове функции
WSARecv
можно указать нулевое значение события
hEvent
. Но следует иметь в виду, что при вызове функции
WSAGetOverlappedResult
с параметром
fWait
, равным
True
, указанное событие служит для ожидания завершения операции, и если событие не задано, возникнет ошибка. Таким образом, если событие не используется, функция
WSAGetOverlappedResult
не может вызываться в режиме ожидания.

Отдельно рассмотрим ситуацию, когда на момент вызова функции

WSARecv
с ненулевым параметром
lpOverlapped
во входном буфере сокета есть данные. В этом случае функция отработает так же, как и в неперекрытом режиме, т.е. изменит значения параметров
NumberOfBytesRecvd
и
Flags
и вернет ноль, свидетельствующий об успешном выполнении функции. Но при этом событие будет взведено, а в структуру
lpOverlapped
будет внесена вся необходимая информация. Благодаря этому последующие вызовы функций
WSAWaitForMultipleEvents
и
WSAGetOverlappedResult
будут выполняться корректно, т.е. таким образом, как если бы функция
WSARecv
завершилась с ошибкой
WSA_IO_PENDING
, и сразу после этого в буфер сокета поступили данные. Это позволяет выполнить обработку результатов операций перекрытого ввода-вывода с помощью одного и того же кода независимо от того, были ли в буфере сокета данные на момент начала операции или нет.

Новая операция перекрытого ввода-вывода может быть начата до того, как закончится предыдущая. Это удобно при работе с несколькими сокетами: можно выполнять операции с ними параллельно в фоновом режиме, получая уведомления о завершении каждой из операций.

В MSDN не написано явно, что будет, если вызвать для сокета функцию

WSARecv
повторно, до того как будет завершена предыдущая операция перекрытого чтения (но запрета на такие действия тоже нет). Эксперименты показывают, что в этом случае операции перекрытого чтения встают в очередь, т.е. первый полученный сокетом пакет приводит к завершению операции, начатой первой, второй пакет — к завершению операции, начатой второй, и т.д. Но поскольку это явно не документировано, лучше не полагаться на то, что такой порядок будет всегда соблюдаться.

В качестве примера реализации перекрытого ввода-вывода рассмотрим, ситуацию, когда программа начинает операцию чтения данных из сокета, время от времени проверяя статус операции (листинг 2.71). События в этом примере не используются, проверка осуществляется с помощью функции

WSAGetOverlappedResult
.

Листинг 2.71. Перекрытый ввод-вывод с использованием функции
WSAGetOverlappedResult

var

 S: TSocket;

 Overlapped: TWSAOverlapped;

 BufPtr: TWSABuf;

 RecvBuf: array[1..100] of Char;

 Cnt, Flags: Cardinal;

begin

 // Инициализация WinSock, создание сокета S, привязка его к адресу

 ......

 // Подготовка структуры, задавшей буфер

 BufPtr.Buf := @RBuf;

 BufPtr.Len := SizeOf(RBuf);

 // Подготовка структуры TWSAOverlapped

 // Поля Internal, InternalHigh, Offset, OffsetHigh программа

 // не устанавливает

 Overlapped.hEvent := 0;

 Flags := 0;

 // Начало операции перекрытого получения данных

 WSARecv(S, @BufPtr, 1, Cnt, Flags, @Overlapped, nil);

 while True do

 begin

if WSAGetOverlappedResult(S, @Overlapped, Cnt, False, Flags) then

begin

// Данные получены, находятся в RecvBuf, обрабатываем

......

// Выходим из цикла Break;

 end

 else if WSAGetLastError <> WSA_IO_INCOMPLETE then

 begin

// Произошла ошибка, анализируем ее

......

// Выходим из цикла

Break;

 end

 else

 begin

// Операция чтения не завершена

// Занимаемся другими действиями

Поделиться:
Популярные книги

Последний попаданец 2

Зубов Константин
2. Последний попаданец
Фантастика:
юмористическая фантастика
попаданцы
рпг
7.50
рейтинг книги
Последний попаданец 2

Попаданка в деле, или Ваш любимый доктор - 2

Марей Соня
2. Попаданка в деле, или Ваш любимый доктор
Любовные романы:
любовно-фантастические романы
7.43
рейтинг книги
Попаданка в деле, или Ваш любимый доктор - 2

Кодекс Крови. Книга ХII

Борзых М.
12. РОС: Кодекс Крови
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Кодекс Крови. Книга ХII

Новый Рал 2

Северный Лис
2. Рал!
Фантастика:
фэнтези
7.62
рейтинг книги
Новый Рал 2

Законы Рода. Том 3

Flow Ascold
3. Граф Берестьев
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 3

Последний Паладин

Саваровский Роман
1. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин

Школа Семи Камней

Жгулёв Пётр Николаевич
10. Real-Rpg
Фантастика:
фэнтези
рпг
5.00
рейтинг книги
Школа Семи Камней

Город Богов

Парсиев Дмитрий
1. Профсоюз водителей грузовых драконов
Фантастика:
юмористическая фантастика
детективная фантастика
попаданцы
5.00
рейтинг книги
Город Богов

Великий князь

Кулаков Алексей Иванович
2. Рюрикова кровь
Фантастика:
альтернативная история
8.47
рейтинг книги
Великий князь

Измена. Свадьба дракона

Белова Екатерина
Любовные романы:
любовно-фантастические романы
эро литература
5.00
рейтинг книги
Измена. Свадьба дракона

Гарем вне закона 18+

Тесленок Кирилл Геннадьевич
1. Гарем вне закона
Фантастика:
фэнтези
юмористическая фантастика
6.73
рейтинг книги
Гарем вне закона 18+

Новые горизонты

Лисина Александра
5. Гибрид
Фантастика:
попаданцы
технофэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Новые горизонты

Морозная гряда. Первый пояс

Игнатов Михаил Павлович
3. Путь
Фантастика:
фэнтези
7.91
рейтинг книги
Морозная гряда. Первый пояс

Вечный. Книга III

Рокотов Алексей
3. Вечный
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга III