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

 begin

AddMessageToLog(

'Внутренняя ошибка сервера — не найдено соединение для сокета');

Exit;

 end;

 // Проверяем, были ли ошибки при взаимодействии

 if Msg.SockError <> 0 then

 begin

AddMessageToLog('Ошибка при взаимодействии с клиентом ' +

Connection.ClientAddr + ': ' + GetErrorString(Msg.SockError));

 RemoveConnection;

 Exit;

 end;

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

 case Msg.SockEvent of

 FD_READ: begin

// Проверяем, на каком этапе находится взаимодействие с клиентом.

if Connection.Phase = tpReceiveLength then

begin

// Этап получения от клиента длины строки. При выполнении этого

 // этапа сервер получает от клиента длину строки и размещает ее

 // в поле Connection.MsgSize. Здесь приходится учитывать, что

 // теоретически даже такая маленькая (4 байта) посылка может

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

 // этап не будет завершен, и второй раз его придется

 // продолжать, загружая оставшиеся байты. Connection.Offset -

 // количество уже прочитанных на данном этапе байтов -

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

 // заполняется буфер.

 Res:= recv(Connection.ClientSocket,

(PChar((PConnection.MsgSize + Connection.Offset)^, Connection.BytesLeft, 0);

 if Res > 0 then

 begin

// Если Res > 0, это означает, что получено Res байтов.

 // Соответственно, увеличиваем на Res количество прочитанных

 // на данном этапе байтов и на такую же величину уменьшаем

// количество оставшихся.

 Inc(Connection.Offset, Res);

 Dec(Connection.BytesLeft, Res);

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

 // переходить к следующему этапу.

 if Connection.BytesLeft = 0 then

begin

// Проверяем корректность принятой длины строки

if Connection.MsgSize <= 0 then

begin

AddMessageToLog('Неверная длина строки, от клиента ' +

Connection.ClientAddr + ': ' + IntToStr(Connection.MsgSize));

RemoveConnection;

 Exit;

end;

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

 Connection.Phase:= tpReceiveString;

// Пока на этом этапе не прочитано ни одного байта

Connection.Offset:= 0;

// Осталось прочитать Connection.MsgSize байтов

 Connection.BytesLeft:= Connection.MsgSize;

 // Сразу выделяем память под строку

 SetLength(Connection.Msg, Connection.MsgSize);

end;

 end

elsе if Res = 0 then

 begin

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

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

 RemoveConnection;

 Exit;

 end

 else

// Ошибку WSAEWOULDBLOCK игнорируем, т. к. она говорит

// только о том, что входной буфер сокета пуст, но в целом

// все в порядке — такое вполне возможно при ложных

// срабатываниях сообщения

if WSAGetLastError <> WSAEWOULDBLOCK then

begin

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

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

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

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

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

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