О чём не пишут в книгах по Delphi
Шрифт:
Str :=
AnsiUpperCase(StringReplace(Str, #0, '#0',
[rfReplaceAll])) + '(AsyncEvent server)';
SendString(Str);
Str := '';
end
else
begin
if StrLen <= 0 then
begin
LogMessage('Неверная длина строки от клиента: ' +
IntToStr(StrLen));
LoopExit := True;
Break;
end;
BytesLeft := StrLen;
SetLength(Str, StrLen);
end;
end
else Inc(Offset, L);
Inc(P, L);
end;
//
Проверяем, был ли аварийный выход из внутреннего цикла,
// и если был, выходим и из внешнего, завершая работу
// с клиентом
if LoopExit then Break;
end
else if RecvRes = 0 then
begin
LogMessage('Клиент закрыл соединение ');
Break;
end
else
begin
if WSAGetLastError <> WSAEWOULDBLOCK then
begin
LogMessage('Ошибка при получении данных от клиента: ' +
GetErrorString);
end;
end;
end;
// Сокет готов к передаче данных
if NetEvents.lNetworkEvents and FD_WRITE <> 0 then
begin
if NetEvents.iErrorCode[FD_WRITE_BIT] <> 0 then
begin
LogMessage('Ошибка в событии FD_WRITE: ' +
GetErrorString(NetEvents.iErrorCode[FD_WRITE_BIT)));
Break;
end;
// Отправляем то, что лежит в буфере
if not DoSendBuf then Break;
end;
if NetEvents.lNetworkEvents and FD_CLOSE <> 0 then
begin
// Клиент закрыл соединение
if NetEvents.iErrorCode[FD_CLOSE_BIT] <> 0 then
begin
LogMessage('Ошибка в событии FD_CLOSE: ' +
GetErrorString(NetEvents.iErrorCode[FD_CLOSE_BIT]));
Break;
end;
LogMessage('Клиент закрыл соединение');
shutdown(FSocket, SD_BOTH);
Break;
end;
end;
WSA_WAIT_FAILED: begin
LogMessage('Ошибка при ожидании сообщения: ' + GetErrorString);
Break;
end;
else begin
LogMessage(
'Внутренняя
ошибка сервера — неверный результат ожидания ' +
IntToStr(WaitRes));
Break;
end;
end;
until False;
closesocket(FSocket);
LogMessage('Нить остановлена');
end;
// Функция возвращает True, если нить завершилась
function TClientThread.GetFinished: Boolean;
begin
// Ждем окончания работы нити с нулевым тайм-аутом.
// Если нить завершена, вернется WAIT_OBJECT_0.
// Если еще работает, вернется WAIT_TIMEOUT.
Result := WaitForSingleObject(Handle, 0) = WAIT_OBJECT_0;
end;
// Метод для остановки нити извне.
// Взводим соответствующее событие, а остальное сделаем
// при обработке события
procedure TClientThread.StopThread;
WSASetEvent(FEvents[0]);
end;
Модуль
WinSock2_Events
, появившийся в списке uses
, содержит объявления констант, типов и функций из WinSock 2, которые понадобятся в программе. Модуль ShutdownConst
содержит объявления констант для функции shutdown
, которые отсутствуют в модуле WinSock Delphi 5 и более ранних версиях — этот модуль нам понадобился, чтобы программу можно было откомпилировать в Delphi 5. Нить использует три события, дескрипторы которых хранятся в массиве
FEvents
. Событие FEvents[0]
служит для уведомления нити о том, что необходимо завершиться, FEvents[1]
— для уведомления о том, что нужно оправить данные, FEvents[2]
связывается с событиями на сокете. Такой порядок выбран не случайно. Если взведено несколько событий, функция WSAWaitForMultipleEvents
вернет результат, соответствующий событию с самым младшим из взведенных событий индексом. Соответственно, чем ближе к началу массива, тем более высокий приоритет у события. Событие, связанное с сокетом, имеет наинизший приоритет для того, чтобы повысить устойчивость сервера к DoS-атакам. Если приоритет этого события был бы выше, чем события остановки нити, то в случае закидывания сервера огромным количеством сообщений от клиента, событие FD_READ
было бы всегда взведено, и сервер все время тратил бы на обработку этого события, игнорируя сигнал об остановке нити. Соответственно, сигнал об остановке должен иметь самый высокий приоритет, чтобы остановке нити ничего не могло помешать. Тем, как отправляются сообщения, сервер управляет сам. поэтому не приходится ожидать проблем, связанных с тратой излишних ресурсов на обработку сигнала отправки. Соответственно, этому событию присваивается приоритет, промежуточный между событием остановки нити и событием сокета.
Поделиться:
Популярные книги
Жалкая
3. Долго и Несчастливо
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Беглец
1. Совсем не герой
Фантастика:
фэнтези
попаданцы
8.94
рейтинг книги
Академия проклятий. Книги 1 - 7
Академия Проклятий
Фантастика:
фэнтези
8.98
рейтинг книги
Измена. Верни мне мою жизнь
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена
Любовные романы:
современные любовные романы
5.38
рейтинг книги
Гардемарин Ее Величества. Инкарнация
1. Гардемарин ее величества
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
фантастика: прочее
5.00
рейтинг книги
Сердце для стража
5. Девятый
Фантастика:
фэнтези
боевая фантастика
9.20
рейтинг книги
Черный Маг Императора 11
11. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Имя нам Легион. Том 3
3. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Жена фаворита королевы. Посмешище двора
Фантастика:
фэнтези
5.00
рейтинг книги
Как я строил магическую империю 5
5. Как я строил магическую империю
Фантастика:
попаданцы
аниме
фантастика: прочее
фэнтези
5.00
рейтинг книги
Блуждающие огни 2
2. Блуждающие огни
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Ратник
3. Помещик
Фантастика:
альтернативная история
7.11
рейтинг книги
Маленькая слабость Дракона Андреевича
1. Танцы на углях
Любовные романы:
современные любовные романы
эро литература
5.25