Question

I have a TCP "Server", that is sending data every 20 seconds. I am trying to receive this data and display the result. Currently, the data is displayed 3 times instead of once. It then waits another 20 seconds, and again displays the data 3 times.

with Client do
begin

    Connect;

    while True do
    begin
        try
        if IOHandler.CheckForDataOnSource(1000) then
        begin
            WriteLn('Bytes available: ' IntToStr(IOHandler.InputBuffer.Size));
            IOHandler.ReadBytes(buffer, IOHandler.InputBuffer.Size);
        end;
        except
            on e : exception do
                writeln(e.message);
        end;

        if(buffer <> nil) then
        begin
            SetString(msg, PAnsiChar(@buffer[0], length(buffer));
            buffer := nil;
            IOHandler.InputBuffer.Clear;
        end;

        write(msg);
    end;
end;
Was it helpful?

Solution 2

I fixed the problem I was having, by moving the write(msg) into the if statement checking if the buffer is not nil.

with Client do
begin

    Connect;

    while True do
    begin
        try
            if IOHandler.CheckForDataOnSource(1000) then
            begin
                WriteLn('Bytes available: ' IntToStr(IOHandler.InputBuffer.Size));
                IOHandler.ReadBytes(buffer, IOHandler.InputBuffer.Size);
            end;
        except
            on e : exception do
                writeln(e.message);
        end;

        if(buffer <> nil) then
        begin
            SetString(msg, PAnsiChar(@buffer[0], length(buffer));
            buffer := nil;
            IOHandler.InputBuffer.Clear;
            write(msg); {only write out the message when the buffer is not nil}
        end;
    end;
end;

OTHER TIPS

You are calling write(msg) on every loop iteration regardless of whether you actually read any new data or not. You are resetting your buffer to nil after assigning it to msg, but you are not resetting msg to '' after writing it. So each loop iteration is writing whatever msg already holds until you assign a new value to it.

Try this code instead:

with Client do
begin
  Connect;
  buffer := nil;
  repeat
    try
      if IOHandler.CheckForDataOnSource(1000) then
      begin
        WriteLn('Bytes available: ' + IntToStr(IOHandler.InputBuffer.Size));
        IOHandler.ReadBytes(buffer, IOHandler.InputBuffer.Size);
        SetString(msg, PAnsiChar(buffer), Length(buffer));
        Write(msg);
        buffer := nil;
      end;
    except
      on E: Exception do
        WriteLn(E.Message);
    end;
  until not Connected;
end;

Which can be simplified to this:

with Client do
begin
  Connect;
  buffer := nil;
  repeat
    try
      IOHandler.ReadBytes(buffer, -1);
      WriteLn('Bytes read: ' + Length(buffer));
      SetString(msg, PAnsiChar(buffer), Length(buffer));
      Write(msg);
      buffer := nil;
    except
      on E: Exception do
        WriteLn(E.Message);
    end;
  until not Connected;
end;

Or even:

with Client do
begin
  Connect;
  repeat
    try
      if IOHandler.CheckForDataOnSource(IdTimeoutDefault) then
      begin
        WriteLn('Bytes available: ' + IntToStr(IOHandler.InputBuffer.Size));
        Write(IOHandler.InputBufferAsString(en8bit));
      end;
    except
      on E: Exception do
        WriteLn(E.Message);
    end;
  until not Connected;
end;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top