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

 Connection.BytesLeft:= Length(Connection.Msg);

end;

 end

else if Res = 0 then

 begin

AddMessageToLog('Клиент ' + Connection.ClientAddr +

' закрыл соединение');

RemoveConnection;

 Exit;

 end

else

// Как обычно, "ошибку" WSAEWOULDBLOCK просто игнорируем

if WSAGetLastError <> WSAEWOULDBLOCK then

begin

AddMessageToLog('Ошибка при получении данных от клиента ' +

Connection.ClientAddr + ': ' + GetErrorString);

 RemoveConnection;

 Exit;

 end;

end;

if Connection.Phase = tpSendString then

begin

// Следующий этап — отправка строки. Код примерно такой же,

 // как и в предыдущем этапе, но вместо recv используется send.

// Кроме того, отсутствует проверка на Res = 0, т. к. при

 // использовании TCP send никогда не возвращает 0.

 Res:=

 send(Connection.ClientSocket, Connection.Msg[Connection.Offset + 1],

 Connection.BytesLeft, 0);

 if Res > 0 then

 begin

Inc(Connection.Offset, Res);

 Dec(Connection.BytesLeft, Res);

 // Если Connection.BytesLeft = 0, значит, строка отправлена

 // полностью.

if Connection.BytesLeft = 0 then

 begin

AddMessageToLog('Клиенту ' + Connection.ClientAddr +

' отправлена строка: ' + Connection.Msg);

 // Очищаем строку, престо сэкономить память

Connection.Msg:= '';

// Следующий этап — снова получение длины строки от клиента

Connection.Phase:= tpReceiveLength;

 // Получено — 0 байт

 Connection.Offset:= 0;

// Осталось прочитать столько, сколько занимает целое число

 Connection.BytesLeft:= SizeOf(Integer);

 end;

 end

 else

if WSAGetLastError <> WSAEWOULDBLOCK then

 begin

AddMessageToLog('Ошибка при отправке данных клиенту ' +

Connection.ClientAddr + ': ' + GetErrorString);

RemoveConnection;

 Exit;

 end;

 end;

end;

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

<p>2.1.17. Параметры сокета</p>

Каждый сокет обладает рядом параметров (опций), которые влияют на его работу. Существуют параметры уровня сокета, которые относятся к сокету как к объекту безотносительно используемого протокола и его уровня. Впрочем, некоторые параметры уровня сокета применимы не ко всем протоколам. Здесь мы не будем рассматривать все параметры сокета, а ограничимся лишь изложением методов доступа к ним и познакомимся с некоторыми самыми интересными параметрами.

Для получения текущего значения параметров сокета предусмотрена функция getsockopt, для изменения — setsockopt. Прототипы этих функций выглядят следующим образом:

function getsockopt(s: TSocket; level, optname: Integer; optval: PChar; var optlen: Integer): Integer;

function setsockopt(s: TSocket; level, optname: Integer; optval: PChar; optlen: Integer): Integer;

Перейти на страницу:

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

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

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

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

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