Читаем О чём не пишут в книгах по Delphi полностью

 // но вероятность блокирования на долгое время мы оцениваем как

 // крайне низкую, т. к. оставшаяся часть сообщения, скорее всего,

 // придет достаточно быстро, и поэтому идем на такой риск.

 for I:= FD_SETSIZE * J to Min(FD_SETSIZE * (J + 1) — 1, Connections.Count — 1) do

if FD_ISSET(PConnection(Connections[I])^.ClientSocket, SockSet) then

ProcessSocketMessage(PConnection(Connections[I])^);

 end;

 // Проверяем поле Deleted у всех соединений. Те, у которых

 // оно равно True, закрываем: закрываем сокет, освобождаем память,

 // удаляем указатель из списка. Цикл идет с конца списка к началу,

 // потому что в ходе работы цикла верхняя граница списка

 // может меняться, и цикл for снизу вверх мог бы привести

 // к появлению индексов вне диапазона.

 for I:= Connections.Count — 1 downto 0 do

 if PConnection(Connections[I])^.Deleted then

 begin

closesocket(PConnection(Connections[I])^.ClientSocket);

 Dispose(PConnection(Connections[I]));

 Connections.Delete(I);

end;

 Sleep(100);

until False;

Функции Ceil и Min, которые встречаются здесь, можно было бы заменить одноимёнными функциями из модуля Math. Но этот модуль входит не во все варианты поставки Delphi, и чтобы пример можно было откомпилировать в любом варианте поставки Delphi, мы описали их здесь самостоятельно (листинг 2.27).

Листинг 2.27. Функции Ceil и Min

// Функция Ceil возвращает наименьшее целое число X, удовлетворяющее

// неравенству X >= А / В

function Ceil(A, B: Integer): Integer;

begin

 Result:= A div B;

 if A mod В <> 0 then Inc(Result);

end;

// Функция Min возвращает меньшее из двух чисел

function Min(А, В: Integer): Integer;

begin

 if A < В then Result:= A

 else Result:= B;

end;

Получившийся сервер более устойчив к DoS-атакам, чем написанный ранее многонитевой сервер. Так как он обходится одной нитью, планировщик задач не перегружается при большом числе подключившихся клиентов. DoS-атака заставляет расходовать только ресурсы библиотеки сокетов и процессорное время, причем вредный эффект последнего легко уменьшить, установив процессу сервера низкий приоритет.

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

Примечание

Многонитевой сервер в этом отношении надежнее: некорректное сообщение клиента заблокирует только ту нить, которая взаимодействует с этим клиентом, никак не влияя на остальные нити, работающие с другими клиентами.

Сделать сервер более устойчивым к некорректным действиям клиента можно, если каждый раз читать ровно столько байтов, сколько пришло. Это усложнит сервер, т. к. придется между "сеансами связи с клиентом" помнить сколько байтов было прочитано в прошлый раз. Однако это поможет полностью избежать блокировок при операциях чтения, что существенно повысит надежность сервера. В этом разделе мы не будем рассматривать соответствующий пример, а реализуем эту возможность в следующем сервере, использующем неблокирующие сокеты. В сервере на основе select это делается совершенно аналогично.

<p>2.1.15. Неблокирующий режим</p>
Перейти на страницу:

Похожие книги

1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных