Question

I have a dummy, test server created using TIdTCPServer which I call from a client app using TIdTCPClient. The OnExecute method of TIdTCPServer is:

procedure TDummySign.OnExecute(AContext: TIdContext);
begin
  Sleep(FDelay);
  // <1>010101<2>060100037908751531342CB30801010801000000000000D69A<3>
  AContext.Connection.IOHandler.Write(#6'01011234'#3#1'010101'#2'060100037908751531342CB30801010801000000000000D69A'#3);

end;

FDelay is set to say 500ms.

What I'm trying to achieve is make multiple requests to this server from my client without re-establishing a connection in between requests. What is happening is when I attempt to read this reply from my client it (the reply) is constantly growing as the OnExecute is continuously executed once I've sent my first request.

Is there a way to, once I've "finished" with this OnExecute event, tell TidTCPServer to wait again until I send through another request from my client? Similar to how it operates before any request has been sent from the client. Some method of some property of TIdTCPServer I could perhaps call? I've tried debugging through Write and calling ClearWriteBuffer (which is always nil so doesn't do anything) and from the Client side I clear the InputBuffer but to no avail.

For reference, here's my client code to send the request:

FIdTCPClient.IOHandler.Writeln(AString);
FIdTCPClient.IOHandler.InputBuffer.Clear;

TotalTime := 0;
TimedOut := False;
Reply := '';
Result := nil;

ParseInput := CreatePacketParserInput(ProtocolType);
repeat
  if FIdTCPClient.IOHandler.CheckForDataOnSource(Interval) then
  begin
    Reply := Reply + FIdTCPClient.IOHandler.InputBufferAsString;
    ParseInput.Reply := Reply;
    FParser.ParseReply(ParseInput, Result, SignId);
    CanContinue := (Result.ParseReplyResponse = TCommsParseReplyResponse.rrOK) or
      (Result.ParseReplyResponse = TCommsParseReplyResponse.rrStartSessionRetry) or
      (Result.ParseReplyResponse = TCommsParseReplyResponse.rrPacketParseError);
  end
  else
  begin
    TotalTime := TotalTime + Interval;
    if TotalTime > FCommsConfig.ReadTimeOut then
      TimedOut := True;
  end;
until TimedOut or (CanContinue);
Was it helpful?

Solution

Your client is using TIdIOHandler.WriteLn() to send a request. On the server side, call TIdIOHandler.ReadLn() to wait for the request before then calling TIdIOHandler.Write() to send the response:

procedure TDummySign.OnExecute(AContext: TIdContext);
var
  Req: string;
begin
  Req := AContext.Connection.IOHandler.ReadLn;
  ...
  AContext.Connection.IOHandler.Write(#6'01011234'#3#1'010101'#2'060100037908751531342CB30801010801000000000000D69A'#3);
  ...
end;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top