Sye*_*ZBK 2 delphi tcp timer indy10
我正在 Delphi 7 中使用 Indy 10 开发一个聊天应用程序。现在,在客户端,Indy 没有 orOnDataReceived事件OnRead,那么我如何从服务器接收文本到客户端呢?
我确实尝试将OnWork事件与计时器一起使用,但我的计时器没有启动。
OnWork以下是我使用的代码TTimer:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if zb_FDataReceived then
  begin
    ShowMessage('Timer triggered!');
    ClientOutput.Lines.Add('Server: ' + zb_FReceivedData);
    zb_FDataReceived := False;
  end;
end;
procedure TForm1.IdTime1Work(ASender: TObject; AWorkMode: TWorkMode;
  AWorkCount: Integer);
begin
  if zb_FDataReceived then
  begin
    ShowMessage('Timer triggered!');
    ClientOutput .Lines.Add('Server: ' + zb_FReceivedData);
    zb_FDataReceived := False;
  end;
end;
大多数 Indy 客户端都是同步TIdTCPClient操作的,这就是为什么传入数据到达时没有事件的原因。在您告诉客户端读取之前,客户端不会从套接字读取数据。这些OnWork事件用于在读取/写入数据时用于状态报告,即更新进度条等。
因此,为了执行您尝试的操作,您可以使用计时器,但不能按照您尝试的方式执行。在每个计时器事件上,您需要以较短的超时时间查询套接字,以查看它是否有数据等待,如果有,则读取它。例如:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if Client.IOHandler.InputBufferIsEmpty then
  begin
    Client.IOHandler.CheckForDataOnSource(0);
    Client.IOHandler.CheckForDisconnect;
    if Client.IOHandler.InputBufferIsEmpty then Exit;
  end;
  // read a message from the Client as needed...
end;
话虽这么说,通常最好使用单独的线程而不是计时器。让线程运行一个循环,其中每次迭代都会从套接字读取数据,直到新消息到达,然后通知主 UI 线程显示该消息。例如:
type
  TReadingThread = class(TThread)
  protected
    FClient: TIdTCPClient;
    procedure Execute; override;
  public
    constructor Create(AClient: TIdTCPClient);
  end;
constructor Create(AClient: TIdTCPClient);
begin
  inherited Create(False);
  FClient := AClient;
end;
procedure TReadingThread.Execute;
begin
  while (not Terminated) and FClient.Connected do
  begin
    // read a message from FClient as needed...
    // update main UI as needed ...
  end;
end;
Client.Connect;
RThread := TReadingThread.Create(Client);
...
Client.Disconnect;
RThread.Terminate;
RThread.WaitFor;
RThread.Free;