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

 SetLength(Connection.Msg, Connection.MsgSize);

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:= tpReceiveString then

begin

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

 // по реализации от этапа чтения длины строки, за исключением

 // того, что теперь буфером, куда помещаются полученные от клиента

// данные, служит не Connection.MsgSize, a Connection.Msg.

Res:=

 recv(Connection.ClientSocket,

Connection.Msg[Connection.Offset + 1], Connection.BytesLeft, 0);

if Res > 0 then begin

Inc(Connection.Offset, Res);

 Dec(Connection.BytesLeft, Res);

// Если количество оставшихся байтов равно нулю, можно переходить

 // к следующему этапу.

 if Connection.BytesLeft = 0 then

 begin

AddMessageToLog('От клиента ' + Connection.ClientAddr +

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

 // Преобразуем строку. В отличие от предыдущих примеров, здесь

 // мы явно добавляем к строке #0. Это связано с тем, что при

 // отправке, которая тоже может быть выполнена не за один раз,

 // мы указываем индекс того символа строки, начиная с которого

 // нужно отправлять данные. И (хотя теоретически вероятность

 // этого очень мала) может возникнуть ситуация, когда за

 // один раз будут отправлены все символы строки, кроме

 // завершающего #0, и тогда при следующей отправке начинать

 // придется с него. Если мы будем использовать тот #0, который

 // добавляется к концу строки автоматически, то в этом случае

 // индекс выйдет за пределы диапазона. Поэтому мы вручную

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

 // ее частью.

Connection.Msg:=

 AnsiUpperCase(StringReplace(Connection.Msg, #0,

'#0', [rfReplaceAll])) + ' (Non-blocking server)'#0;

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

 Connection.Phase:= tpSendString;

 // Отправлено на этом этапе 0 байт

 Connection.Offset:= 0;

// Осталось отправить Length(Connection.Msg) байт.

 // Единицу к длине строки, в отличие от предыдущих примеров,

 // не добавляем, т. к. там эта единица нужна была для того,

 // чтобы учесть добавляемый к строке автоматически символ #0.

 // Здесь мы еще один #0 добавили к строке явно, поэтому

 // он уже учтен в функции Length.

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

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

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

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

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

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