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

на главную - закладки

Жанры

О чём не пишут в книгах по 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

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

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

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

Свадьба по приказу, или Моя непокорная княжна

Чернованова Валерия Михайловна
Любовные романы:
любовно-фантастические романы
5.57
рейтинг книги
Свадьба по приказу, или Моя непокорная княжна

Сборник коротких эротических рассказов

Коллектив авторов
Любовные романы:
эро литература
love action
7.25
рейтинг книги
Сборник коротких эротических рассказов

Отец моего жениха

Салах Алайна
Любовные романы:
современные любовные романы
7.79
рейтинг книги
Отец моего жениха

Вадбольский

Никитин Юрий Александрович
1. Вадбольский
Фантастика:
попаданцы
5.00
рейтинг книги
Вадбольский

Бастард Императора. Том 7

Орлов Андрей Юрьевич
7. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 7

Повелитель механического легиона. Том VIII

Лисицин Евгений
8. Повелитель механического легиона
Фантастика:
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Повелитель механического легиона. Том VIII

В зоне особого внимания

Иванов Дмитрий
12. Девяностые
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
В зоне особого внимания

Таня Гроттер и магический контрабас

Емец Дмитрий Александрович
1. Таня Гроттер
Фантастика:
фэнтези
8.52
рейтинг книги
Таня Гроттер и магический контрабас

Бастард Императора. Том 2

Орлов Андрей Юрьевич
2. Бастард Императора
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бастард Императора. Том 2

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

Борзых М.
11. РОС: Кодекс Крови
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга ХI

Третий

INDIGO
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий

Возвышение Меркурия. Книга 16

Кронос Александр
16. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 16

Идеальный мир для Лекаря 9

Сапфир Олег
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00
рейтинг книги
Идеальный мир для Лекаря 9

Потусторонний. Книга 1

Погуляй Юрий Александрович
1. Господин Артемьев
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Потусторонний. Книга 1