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

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

Жанры

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

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

Шрифт:

 ClientSocket: TSocket;

 ClientAddr: string;

 MsgSize: Integer;

 Msg: string;

 Offset: Integer;

 BytesLeft: Integer;

 Overlapped: TWSAOverlapped;

end;

Основное отличие этого варианта типа

TConnection
от того, что применялся ранее в примерах
NonBlockingServer
и
AsyncSelectServer
(см. разд. 2.1.16
и 2.2.6, а также листинг 2.31) — это отсутствие поля
Phase
, которое хранит этап взаимодействия с клиентом. Разумеется, в программе
OverlappedServer
взаимодействие с клиентом также разбивается на три этапа, но реализуется другой способ для того, чтобы различать этапы — для каждого этапа создается своя процедура завершения.

Примечание

Использование одной процедуры завершения для всех трех этапов и распознавание в ней этапов с помощью поля

Phase
в случае перекрытого ввода-вывода также возможно. Рекомендуем написать такой вариант сервера в качестве самостоятельного упражнения.

Поле

Overlapped
содержит структуру
TWSAOverlapped
, которой программа непосредственно не пользуется, она только передает указатель на эту структуру в функции
WSARecv
и
WSASend
. Напомним, что одновременно может выполняться несколько операций перекрытого ввода-вывода, но у каждой из этих операций должен быть свой экземпляр
TWSAOverlapped
. Гак как в нашем случае с одним клиентом в каждый момент времени может выполняться не более одной операции, мы создаем по одному экземпляру
TWSAOverlapped
на каждого клиента.

Функция для перекрытого подключения клиентов существует — это

AcceptEx
, с которой мы познакомимся в разд. 2.2.12. Но она неудобна при работе совместно с
WSARecv
и
WSASend
, особенно в таком строго типизированном языке, как Delphi. Поэтому подключение клиентов мы будем отслеживать с помощью уже опробованной технологии асинхронных сокетов на сообщениях. Код запуска сервера OverlappedServer выглядит идентично коду запуска AsyncSelectServer (см. листинг 2.30): точно так же создается сокет, ставится в режим прослушивания, а затем его событие
FD_ACCEPT
привязывается к сообщению
WM_ACCEPTMESSAGE

Сам обработчик

WM_ACCEPTMESSAGE
выглядит теперь следующим образом (листинг 2.77).

Листинг 2.77. Обработчик сообщения WM_
ACCEPTMESSAGE

procedure TServerForm.WMAcceptMessage(var Msg: TWMSocketMessage);

var

 NewConnection: PConnection;

 // Сокет, который создается для вновь подключившегося клиента

 ClientSocket: TSocket;

 // Адрес подключившегося клиента

 ClientAddr: TSockAddr;

 // Длина адреса

 AddrLen: Integer;

 // Аргумент для перевода сокета в неблокирующий режим

 Arg: u_long;

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

 Buf: TWSABuf;

 NumBytes, Flags: DWORD;

begin

 //
Страхуемся от "тупой" ошибки

 if Msg.Socket <> FServerSocket then

raise ESocketError.Create(

'Внутренняя ошибка сервера - неверный серверный сокет');

 // Обрабатываем ошибку на сокете, если она есть

 if Msg.SockError <> 0 then

 begin

MessageDlg('Ошибка при подключении клиента:'#13#10 +

GetErrorString(Msg.SockError) +

#13#10'Сервер будет ocтановлен', mtError, [mbOK], 0);

ClearConnections;

closesocket(FServerSocket);

OnStopServer;

Exit;

 end;

 // Страхуемся от ещё одной "тупой" ошибки

 if Msg.SockEvent <> FD_ACCEPT then

raise ESocketError.Create(

'Внутренняя ошибка сервера - неверное событие на сокете');

 AddrLen := SizeOf(TSockAddr);

 ClientSocket := accept(FServerSocket, @ClientAddr, @AddrLen);

 if ClientSocket = INVALID_SOCKET then

 begin

// Если произошедшая ошибка - WSAEWOULDBLOCK, это просто означает

// что на данный момент подключений нет, а вообще все а порядке,

// поэтому ошибку WSAEWOULDBLOCK мы просто игнорируем. Прочие же

// ошибки могут произойти только в случае серьезных проблем,

// которые требуют остановки сервера.

if WSAGetLastError <> WSAEWOULDBLOCK then

begin

MessageDlg('Ошибка при подключении клиента:'#13#10 +

GetErrorString + #13#10'Сервер будет остановлен',

mtError, [mbOK], 0);

ClearConnections;

closesocket(FServerSocket);

OnStopServer;

end;

 end

 else

 begin

// Новый сокет наследует свойства слушающего сокета.

// В частности, он работает в асинхронном режиме,

// и его событие FD_ACCEPT связано с сообщением WM_ACCEPTMESSAGE.

// Так как нам это совершенно не нужно, отменяем асинхронный

// режим и делаем сокет блокирующим.

if WSAAsyncSelect(ClientSocket, Handle, 0, 0) = SOCKET_ERROR then

begin

MessageDlg('Ошибка при отмене асинхронного режима ' +

'подключившегося сокета:'#13#10 + GetErrorString,

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

Измена. Испорченная свадьба

Данич Дина
Любовные романы:
современные любовные романы
короткие любовные романы
5.00
рейтинг книги
Измена. Испорченная свадьба

Последний из рода Демидовых

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

Его наследник

Безрукова Елена
1. Наследники Сильных
Любовные романы:
современные любовные романы
эро литература
5.87
рейтинг книги
Его наследник

Измена. Право на семью

Арская Арина
Любовные романы:
современные любовные романы
5.20
рейтинг книги
Измена. Право на семью

Неудержимый. Книга XIX

Боярский Андрей
19. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга XIX

Волков. Гимназия №6

Пылаев Валерий
1. Волков
Фантастика:
попаданцы
альтернативная история
аниме
7.00
рейтинг книги
Волков. Гимназия №6

Неучтенный. Дилогия

Муравьёв Константин Николаевич
Неучтенный
Фантастика:
боевая фантастика
попаданцы
7.98
рейтинг книги
Неучтенный. Дилогия

Безумный Макс. Ротмистр Империи

Ланцов Михаил Алексеевич
2. Безумный Макс
Фантастика:
героическая фантастика
альтернативная история
4.67
рейтинг книги
Безумный Макс. Ротмистр Империи

Проданная Истинная. Месть по-драконьи

Белова Екатерина
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Проданная Истинная. Месть по-драконьи

Род Корневых будет жить!

Кун Антон
1. Тайны рода
Фантастика:
фэнтези
попаданцы
аниме
7.00
рейтинг книги
Род Корневых будет жить!

Брак по-драконьи

Ардова Алиса
Фантастика:
фэнтези
8.60
рейтинг книги
Брак по-драконьи

Боги, пиво и дурак. Том 3

Горина Юлия Николаевна
3. Боги, пиво и дурак
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Боги, пиво и дурак. Том 3

Отморозок 3

Поповский Андрей Владимирович
3. Отморозок
Фантастика:
попаданцы
5.00
рейтинг книги
Отморозок 3

Ваше Сиятельство 3

Моури Эрли
3. Ваше Сиятельство
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Ваше Сиятельство 3