【问题标题】:Read Input from Indy10从 Indy10 读取输入
【发布时间】:2014-04-24 12:23:38
【问题描述】:

我正在使用 Delphi XE4 中的 Indy10,并尝试与网络上的 TCP 服务器建立简单的 TCP 连接。服务器发送一个简单的 Hello World 消息,然后断开连接,并等待另一个连接。我有以下代码,用于连接并尝试从服务器读取消息。

with Client do
begin
  Host := '10.10.81.122';
  Port := 3490;
  Connect;

    if IOHandler.Connected then
      writeln('Connected!');

    if IOHandler.InputBufferIsEmpty then
    begin
      if  IOHandler.CheckForDataOnSource(1000) then
      begin
        writeln('Buffer size:' + IntToStr(IOHandler.RecvBufferSize));
        IOhandler.ReadBytes(buffer, IOHandler.RecvBufferSize);
      end
      else
        writeln('Message not received');
    end;

end;

当我运行这段代码时,我得到了一个 recvBufferSize 的值,但缓冲区仍然是空的,然后我得到一个连接正常终止的消息。

【问题讨论】:

  • Hello World 是否被换行符终止?在这种情况下,代码可以简单得多(使用 IOHandler.ReadLn)
  • 我更改了发送端的代码,使其以换行符终止。但我还是想知道如何正确使用 IOHandler.ReadBytes
  • 我正在使用 IOHandler.ReadBytes(buf, -1);读取整个套接字缓冲区。

标签: delphi indy10


【解决方案1】:

RecvBufferSize 与实际可读取的数据量无关。 RecvBufferSize 仅指定 Indy 在分配内部缓冲区以从套接字读取原始数据时使用的大小。无论实际读取什么原始数据,都会放在IOHandler.InputBuffer 中,供ReadBytes() 和其他IOHandler 读取方法使用。

改用此代码:

with Client do
begin
  Host := '10.10.81.122';
  Port := 3490;

  try
    Connect;
    WriteLn('Connected!');

    if IOHandler.CheckForDataOnSource(1000) then
    begin
      WriteLn(Bytes available:' + IntToStr(IOHandler.InputBuffer.Size));
      IOHandler.ReadBytes(buffer, IOHandler.InputBuffer.Size);
    end else
      WriteLn('Message not received');
  except
    on E: Exception do
      WriteLn('Error! ' + E.Message);
  end;
end;

或者:

with Client do
begin
  Host := '10.10.81.122';
  Port := 3490;
  ReadTimeout := 1000;

  try
    Connect;
    WriteLn('Connected!');

    IOHandler.ReadBytes(buffer, -1);
    if Length(buffer) > 0 then
      WriteLn('Bytes read:' + IntToStr(Length(buffer)))
    else
      WriteLn('Message not received');
  except
    on E: Exception do
      WriteLn('Error! ' + E.Message);
  end;
end;

话虽如此,但这并不能保证您实际上会收到完整的消息,因为此代码只是在读取读取时可用的任何原始数据。由于您的服务器在数据末尾发送换行符,因此您可以使用 ReadLn() 而不是 ReadBytes() 并让 Indy 等到实际收到换行符:

with Client do
begin
  Host := '10.10.81.122';
  Port := 3490;
  ReadTimeout := 1000;

  try
    Connect;
    WriteLn('Connected!');
    Msg := IOHandler.ReadLn;
    if not IOHandler.ReadLnTimedOut then
      WriteLn('Message read:' + Msg)
    else
      WriteLn('Message not received');
  except
    on E: Exception do
      WriteLn('Error! ' + E.Message);
  end;
end;

或者:

with Client do
begin
  Host := '10.10.81.122';
  Port := 3490;

  try
    Connect;
    WriteLn('Connected!');

    Msg := IOHandler.ReadLn(LF, 1000);
    if not IOHandler.ReadLnTimedOut then
      WriteLn('Message read:' + Msg)
    else
      WriteLn('Message not received');
  except
    on E: Exception do
      WriteLn('Error! ' + E.Message);
  end;
end;

【讨论】:

    猜你喜欢
    • 2011-03-05
    • 2013-05-29
    • 1970-01-01
    • 2013-03-30
    • 2012-02-17
    • 2011-02-12
    • 2013-06-03
    • 2021-08-23
    • 2021-11-08
    相关资源
    最近更新 更多