我刚刚设法让客户端(IdTCPClient)根据需要向服务器(IdTCPServer)发送消息。但是如何让客户端等待响应,或者适当地超时?
干杯,阿德里安
客户端可以使用 IOHandler.Readxxx 方法读取响应,其中大多数允许设置超时。读取超时也可以直接在 IdTCPClient.IOHandler 上指定。
procedure TForm1.ReadTimerElapsed(Sender: TObject);
var
S: String;
begin
...
// connect
IdTCPClient1.Connect;
// send data
...
// use one of the Read methods to read the response.
// some methods have a timeout parameter,
// and others set a timeout flag
S := IdTCPClient1.IOHandler.ReadLn(...);
if IdTCPClient1.IOHandler.ReadLnTimedOut then
...
else
...
end;
例如:
客户:
procedure TForm1.SendCmdButtonClick(Sender: TObject);
var
Resp: String;
begin
Client.IOHandler.WriteLn('CMD');
Resp := Client.IOHandler.ReadLn;
end;
服务器:
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
Cmd: String;
begin
Cmd := AContext.Connection.IOHandler.ReadLn;
...
AContext.Connection.IOHandler.WriteLn(...);
end;
或者,您可以改用该TIdTCPConnection.SendCmd()
方法:
客户:
procedure TForm1.SendCmdButtonClick(Sender: TObject);
begin
// any non-200 reply will raise an EIdReplyRFCError exception
Client.SendCmd('CMD', 200);
// Client.LastCmdResult.Text will contain the response text
end;
服务器:
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
Cmd: String;
begin
Cmd := AContext.Connection.IOHandler.ReadLn;
...
if (Command is Successful) then
AContext.Connection.IOHandler.WriteLn('200 ' + ...);
else
AContext.Connection.IOHandler.WriteLn('500 Some Error Text here');
end;
在后一种情况下,如果您切换到TIdCmdTCPServer
,您可以使用该TIdCmdTCPServer.CommandHandlers
集合在设计时定义您的命令并将每个命令的OnCommand
事件处理程序分配给它们,而不是使用OnExecute
事件来手动读取和解析命令,例如:
// OnCommand event handler for 'CMD' TIdCommandHandler object...
procedure TForm1.IdCmdTCPServer1CMDCommand(ASender: TIdCommand);
begin
...
if (Command is Successful) then
ASender.Reply.SetReply(200, ...);
else
ASender.Reply.SetReply(500, 'Some Error Text here');
end;
自从我使用 Indy 组件(或 Delphi )以来已经有一段时间了,但我相信 TIdTCPClient 不会异步运行,因此没有可以设置的 OnData 或类似事件。
您将需要从父类 (TIdTCPConnection) 中调用其中一种读取方法,例如 ReadLn(...)。或者,您可以考虑使用作为 TIdTCPClient 后代的众多 Indy 组件之一。
可以在此处找到该类的文档。