О чём не пишут в книгах по Delphi
Шрифт:
Листинг 2.20. Код "слушающей" нити
procedure TListenThread.Execute;
// Сокет, созданный для общения с подключившимся клиентом
ClientSocket: TSocket;
// Адрес подключившегося клиента
ClientAddr: TSockAddr;
ClientAddrLen: Integer;
begin
// Начинаем бесконечный цикл
repeat
ClientAddrLen := SizeOf(ClientAddr);
//
Ожидаем подключения клиента
ClientSocket := accept(FServerSocket, @ClientAddr, @ClientAddrLen);
if ClientSocket = INVALID_SOCKET then
begin
// Ошибка в функции accept возникает только тогда, когда
// происходит нечто экстраординарное. Продолжать работу
// в этом случае бессмысленно.
LogMessage('Ошибка при подключении клиента: ' + GetErrorString);
Break;
end;
// Создаем новую нить для обслуживания подключившегося клиента
// и передаём ей сокет, созданный для взаимодействия с ним.
TClientThread.Create(ClientSocket, ClientAddr);
until False;
closesocket(FServerSocket);
LogMessage('Сервер завершил работу');
Synchronize(ServerForm.OnStopServer);
end;
Метод
LogMessage
, существующий у "слушающей" нити, эквивалентен тому, который приведен в листинге 2.7. Код нити типа
TClientThread
, которая отвечает за взаимодействие с одним клиентом, приведен в листинге 2.21. Листинг 2.21. Код нити, реализующей взаимодействие с клиентом
// Сокет для взаимодействия с клиентом создается в главной нити,
// а сюда передается через параметр конструктора. Для формирования
// заголовка сюда же передается адрес подключившегося клиента
constructor TClientThread.Create(ClientSocket: TSocket; const ClientAddr:TSockAddr);
begin
FSocket := ClientSocket;
// Заголовок содержит адрес и номер порта клиента.
// Этот заголовок будет добавляться ко всем сообщениям в лог
// от данного клиента.
FHeader :=
'Сообщение от клиента ' + inet_ntoa(ClientAddr.sin_addr) + ':' +
IntToStr(ntohs(ClientAddr.sin_port)) + ': ';
inherited Create(False);
end;
procedure TClientThread.Execute; var Str: string; StrLen: Integer;
begin
LogMessage('Соединение
установлено');
// Начинаем цикл, из которого выходим только при закрытии
// соединения клиентом или из-за ошибки в сети.
repeat
// Читаем длину присланной клиентом строки и помещаем ее в StrLen
case ReadFromSocket(FSocket, StrLen, SizeOf(StrLen)) of
0: begin
LogMessage('Клиент закрыл соединение');
Break;
end;
– 1: begin
LogMessage('Ошибка при получении данных от клиента: ' +
GetErrorString);
Break;
end;
end;
// Протокол не допускает строк нулевой длины
if StrLen <= 0 then
begin
LogMessage('Неверная длина строки от клиента: ' +
IntToStr(StrLen));
Break;
end;
// Установка длины строки в соответствии с полученным значением
SetLength(Str, StrLen);
// Чтение строки нужной длины
case ReadFromSocket(FSocket, Str[1], StrLen) of
0: begin
LogMessage('Клиент закрыл соединение');
Break;
end;
– 1: begin
LogMessage('Ошибка при получении данных от клиента: ' +
GetErrorString);
Break;
end;
end;
LogMessage('Получена строка: ' + Str);
// Преобразование строки
Str :=
AnsiUpperCase(StringReplace(Str, #0, '#0', [rfReplaceAll]),
' (Multithreaded server)';
// Отправка строки. Отправляется на один байт больше, чем
// длина строки, чтобы завершающий символ #0 тоже попал в пакет
if send(FSocket, Str[1], Length(Str) + 1, 0) < 0 then
begin
LogMessage('Ошибка при отправке данных клиенту: ' +
Поделиться:
Популярные книги
Камень Книга седьмая
7. Камень
Фантастика:
фэнтези
боевая фантастика
6.22
рейтинг книги
Я сделаю это сама
1. Магический XVIII век
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Кровь на эполетах
3. Штуцер и тесак
Фантастика:
альтернативная история
7.60
рейтинг книги
Сыночек в награду. Подари мне любовь
1. Суровые отцы
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Кодекс Крови. Книга ХII
12. РОС: Кодекс Крови
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Найди меня Шерхан
3. Ямпольские-Демидовы
Любовные романы:
современные любовные романы
короткие любовные романы
7.70
рейтинг книги
Идеальный мир для Лекаря 4
4. Лекарь
Фантастика:
фэнтези
юмористическая фантастика
аниме
5.00
рейтинг книги
Релокант. По следам Ушедшего
3. Релокант в другой мир
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Мир-о-творец
8. Помещик
Фантастика:
альтернативная история
5.00
рейтинг книги
Протокол "Наследник"
1. Гибрид
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга VII
7. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
4.75
рейтинг книги
Попаданка в семье драконов
Попаданка в академии драконов
Любовные романы:
любовно-фантастические романы
7.37
рейтинг книги
Новые горизонты
5. Гибрид
Фантастика:
попаданцы
технофэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Скрываясь в тени
2. Теневой путь
Фантастика:
боевая фантастика
7.84