TIdTcpClient 已转移 LastCmdResults

TIdTcpClient has shifted 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 contains always the response of the command issued before the last command

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

TIdTCPClient.Connect()成功后,立即拨打TIdTCPClient.GetResponse()读问候语,TIdTCPClient.Connect()不会给你读,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;

之后您可以根据需要调用TIdTCPClient.SendCmd()