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

  Inc(Connection.Offset, cdTransferred);

  // Формируем буфер для чтения оставшейся части длины

  Buf.Len := Connection.BytesLeft;

  Buf.Buf := PChar(@Connection.MsgSize) + Connection.Offset;

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

  Flags := 0;

  if WSARecv(Connection.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;

end;


// Функция ReadMsgCompleted используется в качестве функции завершения

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

// Она во многом аналогична функции ReadLenCompleted

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

var

 Connection: PConnection;

 Buf: TWSABuf;

 NumBytes, Flags: DWORD;

begin

 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

 begin

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

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

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

  ServerForm.RemoveConnection(Connection);

 end

 else if Connection.BytesLeft = 0 then

 begin

  // Строка получена целиком. Выводим ее на экран.

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

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

  // Формируем ответ

  Connection.Msg :=

   AnsiUpperCase(StringReplace(Connection.Msg, #0,

   '#0', [rfReplaceAll])) + ' (Overlapped server)'#0;

  // Смещение - ноль, осталось отправить полную длину

  Connection.Offset := 0;

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

  // Формируем буфер из строки Connection.Msg

  Buf.Len := Connection.BytesLeft;

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

  // Отправляем строку

  if WSASend(Connection.ClientSocket, @Buf, 1, NumBytes, 0,

   @Connection.Overlapped, SendMsgCompleted) = SOCKET_ERROR then

  begin

   it WSAGetLastError <> WSA_IO_PENDING then

   begin

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

     ' - ошибка при отправке строки: ' + GetErrorString);

    ServerForm.RemoveConnection(Connection);

   end;

  end;

 end

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