Search code examples
delphiindy

TIdTCPClient ReadBytes does not reset the buffer


I use a worker thread to read data with TIdTCPClient, as described in other articles. The thread gets the data with this command:

FClient.IOHandler.ReadBytes (FData,-1,False);

where FClient is the TIdTCPClient and FData is TIdBytes.

This is the reading thread's whole Execute() method:

procedure TReadingThread.Execute;
begin
  inherited;
  if not assigned(FClient.IOHandler) then exit;
  while not terminated do
  begin
    if FClient.IOHandler <> nil then
    begin
      try
        FClient.IOHandler.ReadBytes (FData,-1,False);
        Synchronize(DataReceived);

        SetLength (FData,0);

      except
      end;
    end;
  end;
end;

If I do not use SetLength (FData,0) then the next incoming data is appended to FData. I have never read about it in other discussions.

I am using Delphi RAD Studio 10.3.

Is this known that FData has to be set to 0, or am I doing something wrong?


Solution

  • Setting the AByteCount parameter to -1 tells ReadBytes() to return whatever bytes are available at that moment, reading from the socket first if the InputBuffer is currently empty.

    Setting the AAppend parameter to False tells ReadBytes() to use the TIdBytes' existing memory to read bytes into. If the length of the TIdBytes is shorter than the number of bytes being returned, the length is expanded accordingly. But, if the length is equal or larger, it is left untouched. This allows you to preallocate a buffer and reuse it without reallocating it on each read. But, this does mean that if the length is larger than the number of bytes being returned, any previous data in the unread portion is left untouched.

    if you set the AAppend parameter to True instead, the returned bytes are appended to the very end of the TIdBytes' existing memory, leaving all previous data in the TIdBytes untouched.

    Either way, if you want your DataReceived() method to receive a fresh FData containing just new bytes, you have to reset its length to 0 before each read.