问题描述
我开始使用与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()
。