查看了ReadBuff的源码,我想让他读数据,但设置一个超时时间,在几秒内读不到数据就断开连接。
但ReadBuff函数,并没有超时设置,ReadFromStack函数中有超时参数,但那应该该是ReadFromStack中的超时吧,在ReadBuff中,有while (InputBuffer.Size < AByteCount) do 循环,所以还是没法设置超时,ReadFromStack函数ReadTimeout参数,具体实现我看不太明白,不知道有没有方法简单实现下几秒内读不到数据就中断,而不要让他一直在循环着读取呢。
 procedure TIdTCPConnection.ReadBuffer(var ABuffer; const AByteCount: Integer);
begin
  if (AByteCount > 0) and (@ABuffer <> nil) then begin
    // Read from stack until we have enough data
    while (InputBuffer.Size < AByteCount) do begin
      ReadFromStack;
      CheckForDisconnect(True, True);
    end;
    // Copy it to the callers buffer
    Move(InputBuffer.Memory^, ABuffer, AByteCount);
    // Remove used data from buffer
    InputBuffer.Remove(AByteCount);
  end;
end;function TIdTCPConnection.ReadFromStack(const ARaiseExceptionIfDisconnected: Boolean = True;
  ATimeout: Integer = IdTimeoutDefault; const ARaiseExceptionOnTimeout: Boolean = True): Integer;
// Reads any data in tcp/ip buffer and puts it into Indy buffer
// This must be the ONLY raw read from Winsock routine
// This must be the ONLY call to RECV - all data goes thru this method
begin
  ....源代码太长了,不帖了
end;

解决方案 »

  1.   

    我另外写了个函数,不知道正不正确。
    只是把循环给去掉了,传入了超时变量,但不知道这样写,一次从Stack中读取数据,能读取多少。如果一次只能读取一个很小的大小,那就不行了。
    procedure ReadBuff(AThread: TIdPeerThread; var ABuffer; const AByteCount: Longint; ATimeout: Integer = -1);
    begin
      if (AByteCount <= 0) or (@ABuffer = nil) then Exit;  with AThread.Connection do begin
        ReadFromStack(True, ATimeout, True);
        CheckForDisconnect(True, True);    if (InputBuffer.Size >= AByteCount) then begin
          // Copy it to the callers buffer
          Move(InputBuffer.Memory^, ABuffer, AByteCount);
          // Remove used data from buffer
          InputBuffer.Remove(AByteCount);
        end;
      end;
    end;