简体   繁体   English

TIdTCPServer有时无法从套接字读取数据

[英]TIdTCPServer not reading data from socket sometimes

I have the following code in the OnExecute of a TIdTCPServer (Delphi 2009 and Indy 10 that came with the installation) which is very similar to other examples on this site; 我在TIdTCPServer的OnExecute中安装了以下代码(安装过程中随附的Delphi 2009和Indy 10),与该站点上的其他示例非常相似;

   Socket := AContext.Connection.Socket;
    if Socket.CheckForDataOnSource(10) then
    begin
      if not Socket.InputBufferIsEmpty then
      begin
        Socket.InputBuffer.ExtractToBytes(RawBytes, -1, False, -1);

        SetLength(Buffer, Length(RawBytes));
        Move(RawBytes[0], Buffer[1], Length(RawBytes));

        // Do stuff with data here...
      end;
    end;
    AContext.Connection.CheckForGracefulDisconnect;

It doesn't read the data in sometimes as CheckForDataOnSource(10) returns False. 由于CheckForDataOnSource(10)返回False,有时它不会读取数据。 However if I stop the debugger at that line I can see the data I sent in the InputBuffer's bytes. 但是,如果我在该行停止调试器,则可以在InputBuffer的字节中看到发送的数据。 Are there any other setup things I should do or other ways to force this to work all the time. 是否还有其他应做的设置工作或其他方法可以强制其始终正常运行。 This code is run bunch of times but always fails on the CheckForDataOnSource(10). 该代码运行了很多次,但始终在CheckForDataOnSource(10)上失败。

Also as a side note, I notice in code for Indy around the place that some people grab the AContext.Connection.IOHandler instead of the AContext.Connection.Socket and do the same things as the code above, what is the "right" one to use. 另外,我注意到在Indy的代码中,有些人抓住了AContext.Connection.IOHandler而不是AContext.Connection.Socket,并执行与上面的代码相同的操作,什么是“正确”的代码?使用。

Thanks 谢谢

Bruce 布鲁斯

The code should be more like this: 该代码应该更像这样:

var
  IO: TIdIOHandler.
  Buffer: RawByteString;
begin
  IO := AContext.Connection.IOHandler;

  if IO.InputBufferIsEmpty then
  begin
    IO.CheckForDataOnSource(10);
    if IO.InputBufferIsEmpty then Exit;
  end;

  IO.InputBuffer.ExtractToBytes(RawBytes, -1, False, -1);     
  // or: IO.ReadBytes(RawBytes, -1, False);

  SetLength(Buffer, Length(RawBytes));
  BytesToRaw(RawBytes, Buffer[1], Length(RawBytes));
  // Do stuff with Buffer here...
end;

It looks like your code should look like this; 看起来您的代码应如下所示;

Socket := AContext.Connection.Socket;
Socket.CheckForDataOnSource(10);
if not Socket.InputBufferIsEmpty then
begin
  Socket.InputBuffer.ExtractToBytes(RawBytes, -1, False, -1);

  SetLength(Buffer, Length(RawBytes));
  Move(RawBytes[0], Buffer[1], Length(RawBytes));

  // Do stuff with data here...
end;
AContext.Connection.CheckForGracefulDisconnect;

It doesn't matter what IOHandler you grab, so the generic one seems like the go. 抓取什么IOHandler无关紧要,因此通用类似乎很容易。

Sorry about answering my own question but it might be hepful for someone... maybe. 很抱歉回答我自己的问题,但对某人可能会很有益...也许。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM