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

// для перекрытого чтения длины строки

procedure ReadLenCompleted(dwError: DWORD; cdTransferred: DWORD; lpOverlapped: PWSAOverlapped; dwFlags: DWORD); stdcall;

var

 // Указатель на соединение

 Connection: PConnection;

 // Указатель на буфер

 Buf: TWSABuf;

 // Параметры для WSARecv

 NumBytes, Flags: DWORD;

begin

 // Для идентификации операции в функцию передается указатель

 // на запись TWSAOverlapped. Ищем по этому указателю

 // подходящее соединение в списке FConnections.

 Connection := ServerForm.GetConnectionByOverlapped(lpOverlapped);

 if Connection = nil then

 begin

  ServerForm.AddMessageToLog(

   'Внутренняя ошибка программы - не найдено соединение');

  Exit;

 end;

 // Проверяем, что не было ошибки

 if dwError <> 0 then

 begin

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

   ' - ошибка при чтении длины строки: ' + GetErrorString(dwError));

  ServerForm.RemoveConnection(Connection);

  Exit;

 end;

 // Уменьшаем число оставшихся к чтению байтов

 // на размер полученных данных

 Dec(Connection.BytesLeft, cdTransferred);

 if Connection.BytesLeft < 0 then


  // Страховка от "тупой" ошибки

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

   ' - внутренняя ошибка программы: получено больше байтов, ' +

   'чем ожидалось');

  ServerForm.RemoveConnection(Connection);

 end

 else if Connection.BytesLeft = 0 then

 begin

  // Длина строки прочитана целиком

  if Connection.MsgSize <= 0 then

  begin

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

    ' — получена неверная длина строки ' +

    IntToStr(Conneсtion.MsgSizе));

   ServerForm.RemoveConnection(Connection);

   Exit;

  end;

  // Делаем строку нужной длины

  SetLength(Connection.Msg, Connection.MsgSize);

  // Данные пока не прочитаны, поэтому смещение - ноль,

  // осталось прочитать полную длину.

  Connection.Offset := 0;

  Connection.BytesLeft := Connection.MsgSize;

  // Заносим размер буфера и указатель на него в Buf.

  // Данные будут складываться в строку,

  // на которую ссылается Connection.Msg.

  Buf.Len := Connection.MsgSize;

  Buf.Buf := Pointer(Connection.Msg);

  // Вызываем WSARecv для чтения самой строки

  Flags := 0;

  if WSARecv(Connect ion.ClientSocket, @Buf, 1, NumBytes, Flags,

   @Connection.Overlapped, ReadMsgCompleted) = SOCKET_ERROR then

  begin

   if WSAGetLastError <> WSA_IO_PENDING then

   begin

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

     ' - ошибка при чтении строки: ' + GetErrorString(dwError));

    ServerForm.RemoveConnection(Connection);

   end;

  end;

 end

 else

 begin

  // Connection.BytesLeft < 0 - длина строки

  // прочитана не до конца.

  // Увеличиваем смещение на число прочитанных байтов

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже