【问题标题】:Indy TIdTCPClient receive textIndy TIdTCPClient 接收文本
【发布时间】:2019-10-01 08:37:51
【问题描述】:

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

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 时,我确实收到了它。

我做错了什么?

【问题讨论】:

  • receivedtext = '' = false 甚至可以编译吗? (请出示您的真实代码)
  • 为什么要清除InputBuffer?在成功的 Read... 操作后,Indy 将从 InputBuffer 中删除读取的字节。
  • 为什么你的计时器中有这段代码?使用如图所示的代码,您将遇到重入问题,尤其是在计时器值为 8 毫秒的情况下。
  • 我认为您的代码完全错误。使用 google 搜索示例,例如 ...sourceforge.net/projects/indy10clieservr 那里的第一个演示应该有助于“1_sample Simple String Exchange”

标签: delphi timer tcpclient indy


【解决方案1】:

改用类似的东西:

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;

话虽如此,这种代码最好使用工作线程而不是计时器来实现。

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

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 - 修改你的连接代码:

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;

【讨论】:

    猜你喜欢
    • 2015-12-28
    • 2011-06-27
    • 2011-09-24
    • 2017-05-09
    • 2012-07-29
    • 2014-06-12
    • 2015-05-29
    • 2019-07-01
    • 1970-01-01
    相关资源
    最近更新 更多