Delphi (Indy) 客户端发送服务器请求,如何等待响应?

3

我刚刚成功让客户端(IdTCPClient)按照要求向服务器(IdTCPServer)发送了一条消息。但是,如何让客户端等待响应或适当超时呢?

谢谢, Adrian

3个回答

3
客户端可以使用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;

参见:如何使用IdTCPClient等待从服务器返回的字符串?


1
例如:
客户:
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;

0

我已经有一段时间没有使用Indy组件了(或者说Delphi),但我认为TIdTCPClient不是异步的,因此没有可以设置的OnData或类似的事件。

您需要从父类(TIdTCPConnection)调用其中一个读取方法,例如ReadLn(...)。或者,您可以考虑使用许多TIdTCPClient后代的Indy组件之一。

该类的文档可以在这里找到。


好的,假设服务器刚刚写出了一些值:AContext.Connection.IOHandler.WriteLn(EntryRecord.Text);客户端应该怎么做才能接收到这个值呢?我对这一步有点困惑。感谢您的快速回复,Dylan! - Adrian
WriteLn() 发送一个以 CRLF 为分隔符的字符串。TIdIOHandler.ReadLn() 方法读取一个带有分隔符的字符串,其中 LF 是默认的分隔符(当分隔符是 LF 时,ReaDLn() 在内部考虑了 CRLF)。 - Remy Lebeau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接