【问题标题】:Wait for data with Indy10使用 Indy10 等待数据
【发布时间】:2014-05-02 12:04:04
【问题描述】:

我有一个 TCP“服务器”,它每 20 秒发送一次数据。我正在尝试接收这些数据并显示结果。目前,数据显示 3 次而不是 1 次。然后再等待 20 秒,再次显示数据 3 次。

with Client do
begin

    Connect;

    while True do
    begin
        try
        if IOHandler.CheckForDataOnSource(1000) then
        begin
            WriteLn('Bytes available: ' IntToStr(IOHandler.InputBuffer.Size));
            IOHandler.ReadBytes(buffer, IOHandler.InputBuffer.Size);
        end;
        except
            on e : exception do
                writeln(e.message);
        end;

        if(buffer <> nil) then
        begin
            SetString(msg, PAnsiChar(@buffer[0], length(buffer));
            buffer := nil;
            IOHandler.InputBuffer.Clear;
        end;

        write(msg);
    end;
end;

【问题讨论】:

  • 现在它正在控制台应用程序中运行。只是想写一些简单的测试代码,尝试从套接字连接中读取数据。
  • 它在程序过程体内。除了设置主机和端口号之外,这几乎就是所有代码。

标签: delphi indy10


【解决方案1】:

无论您是否实际读取任何新数据,您都在每次循环迭代中调用write(msg)。在将buffer 分配给msg 之后,您将其重置为nil,但在写入之后您并未将msg 重置为''。因此,每次循环迭代都会写入 msg 已经存在的任何内容,直到您为其分配新值。

试试这个代码:

with Client do
begin
  Connect;
  buffer := nil;
  repeat
    try
      if IOHandler.CheckForDataOnSource(1000) then
      begin
        WriteLn('Bytes available: ' + IntToStr(IOHandler.InputBuffer.Size));
        IOHandler.ReadBytes(buffer, IOHandler.InputBuffer.Size);
        SetString(msg, PAnsiChar(buffer), Length(buffer));
        Write(msg);
        buffer := nil;
      end;
    except
      on E: Exception do
        WriteLn(E.Message);
    end;
  until not Connected;
end;

可以简化为:

with Client do
begin
  Connect;
  buffer := nil;
  repeat
    try
      IOHandler.ReadBytes(buffer, -1);
      WriteLn('Bytes read: ' + Length(buffer));
      SetString(msg, PAnsiChar(buffer), Length(buffer));
      Write(msg);
      buffer := nil;
    except
      on E: Exception do
        WriteLn(E.Message);
    end;
  until not Connected;
end;

甚至:

with Client do
begin
  Connect;
  repeat
    try
      if IOHandler.CheckForDataOnSource(IdTimeoutDefault) then
      begin
        WriteLn('Bytes available: ' + IntToStr(IOHandler.InputBuffer.Size));
        Write(IOHandler.InputBufferAsString(en8bit));
      end;
    except
      on E: Exception do
        WriteLn(E.Message);
    end;
  until not Connected;
end;

【讨论】:

  • 我把write语句留在了循环中,因为我刚刚用C写完类似的东西,我注意到当套接字被阻塞等待recv()时。
【解决方案2】:

我通过将 write(msg) 移动到 if 语句中检查缓冲区是否不为零来解决了我遇到的问题。

with Client do
begin

    Connect;

    while True do
    begin
        try
            if IOHandler.CheckForDataOnSource(1000) then
            begin
                WriteLn('Bytes available: ' IntToStr(IOHandler.InputBuffer.Size));
                IOHandler.ReadBytes(buffer, IOHandler.InputBuffer.Size);
            end;
        except
            on e : exception do
                writeln(e.message);
        end;

        if(buffer <> nil) then
        begin
            SetString(msg, PAnsiChar(@buffer[0], length(buffer));
            buffer := nil;
            IOHandler.InputBuffer.Clear;
            write(msg); {only write out the message when the buffer is not nil}
        end;
    end;
end;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-05
    • 1970-01-01
    • 2016-05-03
    • 2021-05-25
    • 2019-08-29
    • 2014-01-16
    • 1970-01-01
    相关资源
    最近更新 更多