Reputation: 193
I started implementing a system using a client server connection with a TIdCmdTcpServer and a TIdTcpClient. The connection is established fine and communication seems to work in general, too. But LastCmdResults contains always the response of the command issued before the last command. It starts with an empty response for the TcpClient.Connect and then continues with a "welcome" as a response to the first TcpClient.SendCmd ('LIST'). When I issue the LIST command again I get the desired result but for the one before (tested with a counter variable).
Relevant Code Snippets:
Initialising Command Handler
CmdHandler := TCPCmdServer.CommandHandlers.Add;
CmdHandler.Name := 'cmhList';
CmdHandler.Command := 'LIST';
CmdHandler.OnCommand := Cmd_ListDevices;
CmdHandler.ExceptionReply.NumericCode := 550;
CmdHandler.Disconnect := FALSE;
TCPCmdServer.Active := TRUE;
Command handler event Cmd_ListDevices
procedure TSPM_Server.Cmd_ListDevices (aSender : TIdCommand);
begin
aSender.Reply.SetReply (200, 'List');
aSender.Reply.Text.Add ('Device 1');
aSender.Reply.Text.Add ('Device 2');
aSender.Reply.Text.Add ('Device 3');
aSender.SendReply;
end;
Client Side
function TSPM_TCPClient.Connect (var aResponseText : string) : boolean;
begin
TcpClient.Connect;
aResponseText := TcpClient.LastCmdResult.Text.Text;
result := TcpClient.Connected;
end;
function TSPM_TCPClient.RequestList (var aList : string) : integer;
begin
aList := '';
result := TcpClient.SendCmd ('LIST');
if result = 200 then
begin
aList := 'CMD: ' + TcpClient.LastCmdResult.DisplayName + sLineBreak
+ TcpClient.LastCmdResult.Text.Text;
end;
end;
Anything obviously wrong here?
Upvotes: 1
Views: 327
Reputation: 597036
LastCmdResults contains always the response of the command issued before the last command
That happens when you have the server setup to send a greeting when a new client connects (see the TIdCmdTCPServer.Greeting
property), but your client code is not reading that greeting. The greeting remains in the client's receive buffer until it is read. So, the 1st SendCmd()
will read the greeting, then the 2nd SendCmd()
will read the response of the 1st SendCmd()
, and so on.
After TIdTCPClient.Connect()
is successful, call TIdTCPClient.GetResponse()
immediately to read the greeting, TIdTCPClient.Connect()
will not read it for you, eg:
function TSPM_TCPClient.Connect (var aResponseText : string) : boolean;
begin
TcpClient.Connect;
try
TcpClient.GetResponse(200); // <-- add this!
aResponseText := TcpClient.LastCmdResult.Text.Text;
Result := True;
except
TcpClient.Disconnect;
Result := False;
end;
end;
Then you can call TIdTCPClient.SendCmd()
afterwards as needed.
Upvotes: 1