TIdTCPServer иногда не читает данные из сокета - PullRequest
2 голосов
/ 02 октября 2009

У меня есть следующий код в OnExecute TIdTCPServer (Delphi 2009 и Indy 10, поставляемый с установкой), который очень похож на другие примеры на этом сайте;

   Socket := AContext.Connection.Socket;
    if Socket.CheckForDataOnSource(10) then
    begin
      if not Socket.InputBufferIsEmpty then
      begin
        Socket.InputBuffer.ExtractToBytes(RawBytes, -1, False, -1);

        SetLength(Buffer, Length(RawBytes));
        Move(RawBytes[0], Buffer[1], Length(RawBytes));

        // Do stuff with data here...
      end;
    end;
    AContext.Connection.CheckForGracefulDisconnect;

Иногда данные не считываются, поскольку CheckForDataOnSource (10) возвращает False. Однако, если я остановлю отладчик в этой строке, я смогу увидеть отправленные мной данные в байтах InputBuffer. Есть ли какие-то другие настройки, которые я должен сделать, или другие способы заставить это работать постоянно. Этот код запускается несколько раз, но всегда завершается ошибкой в ​​CheckForDataOnSource (10).

Также в качестве примечания я заметил в коде для Indy, где некоторые люди берут AContext.Connection.IOHandler вместо AContext.Connection.Socket и делают то же самое, что и приведенный выше код, что такое " правильно "использовать.

Спасибо

Bruce

Ответы [ 2 ]

5 голосов
/ 06 октября 2009

Код должен быть примерно таким:

var
  IO: TIdIOHandler.
  Buffer: RawByteString;
begin
  IO := AContext.Connection.IOHandler;

  if IO.InputBufferIsEmpty then
  begin
    IO.CheckForDataOnSource(10);
    if IO.InputBufferIsEmpty then Exit;
  end;

  IO.InputBuffer.ExtractToBytes(RawBytes, -1, False, -1);     
  // or: IO.ReadBytes(RawBytes, -1, False);

  SetLength(Buffer, Length(RawBytes));
  BytesToRaw(RawBytes, Buffer[1], Length(RawBytes));
  // Do stuff with Buffer here...
end;
0 голосов
/ 02 октября 2009

Похоже, ваш код должен выглядеть так:

Socket := AContext.Connection.Socket;
Socket.CheckForDataOnSource(10);
if not Socket.InputBufferIsEmpty then
begin
  Socket.InputBuffer.ExtractToBytes(RawBytes, -1, False, -1);

  SetLength(Buffer, Length(RawBytes));
  Move(RawBytes[0], Buffer[1], Length(RawBytes));

  // Do stuff with data here...
end;
AContext.Connection.CheckForGracefulDisconnect;

Неважно, какой IOH и какой вы захватите, так что общий вид выглядит как ход.

Извините, что отвечаю на мой вопрос, но это может быть полезно для кого-то ... может быть.

...