Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 等待具有Indy10的数据_Delphi_Indy10 - Fatal编程技术网

Delphi 等待具有Indy10的数据

Delphi 等待具有Indy10的数据,delphi,indy10,Delphi,Indy10,我有一个TCP“服务器”,每20秒发送一次数据。我正在尝试接收此数据并显示结果。目前,数据显示3次,而不是一次。然后再等待20秒,再次显示数据3次 with Client do begin Connect; while True do begin try if IOHandler.CheckForDataOnSource(1000) then begin WriteLn('Bytes availa

我有一个TCP“服务器”,每20秒发送一次数据。我正在尝试接收此数据并显示结果。目前,数据显示3次,而不是一次。然后再等待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;
使用客户端do
开始
连接
尽管如此
开始
尝试
如果IOHandler.CheckForDataOnSource(1000),则
开始
WriteLn('Bytes available:'IntToStr(IOHandler.InputBuffer.Size));
ReadBytes(缓冲区,IOHandler.InputBuffer.Size);
结束;
除了
关于e:exception-do
书面(电子讯息);
结束;
如果(缓冲区为零),则
开始
设置字符串(msg,PAnsiChar(@buffer[0],长度(buffer));
缓冲区:=零;
IOHandler.InputBuffer.Clear;
结束;
写(msg);
结束;
结束;

您正在调用
write(msg)
在每次循环迭代中,无论您是否实际读取任何新数据。在将
缓冲区分配给
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(msg)移到if语句中检查缓冲区是否为nil,我修复了我遇到的问题

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;
使用客户端do
开始
连接
尽管如此
开始
尝试
如果IOHandler.CheckForDataOnSource(1000),则
开始
WriteLn('Bytes available:'IntToStr(IOHandler.InputBuffer.Size));
ReadBytes(缓冲区,IOHandler.InputBuffer.Size);
结束;
除了
关于e:exception-do
书面(电子讯息);
结束;
如果(缓冲区为零),则
开始
设置字符串(msg,PAnsiChar(@buffer[0],长度(buffer));
缓冲区:=零;
IOHandler.InputBuffer.Clear;
write(msg){仅当缓冲区不是nil时才写出消息}
结束;
结束;
结束;

现在它在控制台应用程序中运行。只想编写一些简单的测试代码,尝试从套接字连接读取数据。它位于程序过程的主体中。除了设置主机和端口号外,几乎所有的代码都在这里。我将write语句留在循环中,因为我刚刚完成在C中编写类似的代码时,我注意到当套接字被阻塞时,等待recv()。