TIdTcpClient已转移LastCmdResults

问题描述

我开始使用与TIdCmdTcpserver和TIdTcpClient的客户端服务器连接来实现系统。 可以很好地建立连接,并且通讯似乎也可以正常工作。但是LastCmdResults始终包含在最后一条命令之前发出的命令的响应。它以对TcpClient.Connect的空响应开始,然后以对第一个TcpClient.SendCmd('LIST')的响应继续“欢迎”。当我再次发出LIST命令时,我得到了所需的结果,但之前的结果却是(用计数器变量进行了测试)。

相关代码段:

初始化命令处理程序

  CmdHandler := TCPCmdserver.CommandHandlers.Add;
  CmdHandler.Name := 'cmhList';
  CmdHandler.Command := 'LIST';
  CmdHandler.OnCommand := Cmd_ListDevices;
  CmdHandler.ExceptionReply.NumericCode := 550;
  CmdHandler.disconnect := FALSE;

  TCPCmdserver.Active := TRUE;

命令处理程序事件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;

客户端

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;

这里显然有什么不对吗?

解决方法

LastCmdResults始终包含在最后一条命令之前发出的命令的响应

当服务器设置为在新客户端连接时发送问候语(请参见TIdCmdTCPServer.Greeting属性),但是客户端代码没有读取该问候语时,就会发生这种情况。问候语将一直保留在客户端的接收缓冲区中,直到被读取为止。因此,第一个SendCmd()将读取问候语,然后第二个SendCmd()将读取第一个SendCmd()的响应,依此类推。

TIdTCPClient.Connect()成功后,立即呼叫TIdTCPClient.GetResponse()以阅读问候语,TIdTCPClient.Connect()不会为您阅读问候语,例如:

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;

然后,您可以根据需要稍后致电TIdTCPClient.SendCmd()