Indy TIdTCPClient接收文本 [英] Indy TIdTCPClient receive text

查看:532
本文介绍了Indy TIdTCPClient接收文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试在idtcpclient中接收文本,但是它不起作用。这是我在计时器中使用的代码:

I try to receive text in a idtcpclient but it does not work. This is the code that I use in a timer:

procedure TForm1.Timer2Timer(Sender: TObject);
var
  receivedtext:string;
begin
  if idtcpclient1.Connected = true then
  begin
    with idtcpclient1 do
    begin
      if not IOHandler.InputBufferIsEmpty then
      begin
        try
          receivedtext := IOHandler.ReadLn;
        finally
          if receivedtext = '' = false then
          begin
            showmessage(receivedtext);
            idtcpclient1.IOHandler.InputBuffer.Clear;
            receivedtext := '';
          end;
        end;
      end;
    end;
  end
  else
  begin
    timer2.Enabled := false;
  end;
end;

计时器的间隔为8毫秒。
计时器在连接时自动启用。
但是我发送邮件时没有收到消息框或错误消息。
我确信我写了数据,因为当我使用 tclientsocket 时,我确实会收到它。

The interval of the timer is 8 ms. The timer is automatically enabled on connect. But I don't get an messagebox or an error when I send something. I am sure that I written the data because when I use tclientsocket I do receive it.

我在做什么错?

推荐答案

请改用类似以下的内容:

Use something more like this instead:

procedure TForm1.Timer2Timer(Sender: TObject);
var
  receivedtext: string;
begin
  with IdTCPClient1 do
  begin
    try
      if IOHandler.InputBufferIsEmpty then
      begin
        IOHandler.CheckForDataOnSource(0);
        IOHandler.CheckForDisconnect;
        if IOHandler.InputBufferIsEmpty then Exit;
      end;
      receivedtext := IOHandler.ReadLn;
    except
      Timer2.Enabled := False;
      Exit;
    end;
    if receivedtext <> '' then
      ShowMessage(receivedtext);
  end;
end;

话虽如此,使用工作者线程而不是计时器可以更好地实现这种代码。

With that said, this kind of code would be better implemented using a worker thread instead of a timer.

1-创建一个从 TThread (文件>新建>其他>线程对象)派生的新类

1 - Create a new class derived from TThread (File > New > Other > Thread Object)

type
  TDataEvent = procedure(const Data: string) of object;

  TReadingThread = class(TThread)
  private
    FClient: TIdTCPClient;
    FData: string;
    FOnData: TDataEvent;
    procedure DataReceived;
  protected
    procedure Execute; override;
  public
    constructor Create(AClient: TIdTCPClient); reintroduce;
    property OnData: TDataEvent read FOnData write FOnData;
  end;

constructor TReadingThread.Create(AClient: TIdTCPClient);
begin
  inherited Create(True);
  FClient := AClient;
end;

procedure TReadingThread.Execute;
begin
  while not Terminated do
  begin
    FData := FClient.IOHandler.ReadLn;
    if (FData <> '') and Assigned(FOnData) then
      Synchronize(DataReceived);
  end;
end;

procedure TReadingThread.DataReceived;
begin
  if Assigned(FOnData) then
    FOnData(FData);
end;

2-修改您的连接代码:

2 - Modify your connection code:

IdTCPClient1.Connect;
try
  Thread := TReadingThread.Create(IdTCPClient1);
  Thread.OnData := DataReceived;
  Thread.Resume;
except
  IdTCPClient1.Disconnect;
  raise;
end;

...

if Assigned(Thread) then Thread.Terminate;
try
  IdTCPClient1.Disconnect;
finally
  if Assigned(Thread) then
  begin
    Thread.WaitFor;
    FreeAndNil(Thread);
  end;
end;

...

procedure TForm1.DataReceived(const Data: string);
begin
  ShowMessage(Data);
end;

这篇关于Indy TIdTCPClient接收文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆