【问题标题】:Getting a lot of "Read timed out" exceptions from Indy's IdTCPServer从 Indy 的 IdTCPServer 获取大量“读取超时”异常
【发布时间】:2020-06-10 11:38:12
【问题描述】:

“读取超时”异常在 ReadBytes(B1, 600, False) 引发 50% 的连接请求和 20% 在 ReadBytes(B3, 5, False)。所以只有少数连接正确完成。 我知道在客户端制作 600 个字节的过程不会超过 2 秒。顺便说一句,如果我将 ReadTimeout 从 10000 增加到 20000,结果并没有改善。 大约有 50 个客户端通常在不同的时间连接,所以我们没有拥挤的服务器。 我设置 ReadTimeout 的目标是在出现问题时尽快关闭连接。 我的代码有什么问题,还是应该在其他地方搜索问题?

procedure TForm1.IdTCPServerExecute(AContext: TIdContext);
var
  Log: TConnectionLog;
  B1, B2, B3: TIdBytes;
begin
  try
    try
      Log := TConnectionLog.Create;
      Log.ConnectDateTime := Now;
      Log.ClientIP := AContext.Binding.PeerIP;

      AContext.Connection.IOHandler.ReadTimeout := 10000; 
      AContext.Connection.IOHandler.ReadBytes(B1, 600, False);
      AContext.Connection.IOHandler.ReadTimeout := IdTimeoutDefault;
      Log.Bytes600ReceiveDateTime := Now;

      SetLength(B2, 200);
      AContext.Connection.IOHandler.Write(B2);
      Log.Bytes200SendDateTime := Now;

      AContext.Connection.IOHandler.ReadTimeout := 15000; 
      AContext.Connection.IOHandler.ReadBytes(B3, 5, False);
      AContext.Connection.IOHandler.ReadTimeout := IdTimeoutDefault;
      Log.Bytes5ReceiveDateTime := Now;
    except
      on E: Exception do
      begin
        Log.ExceptionMessage := E.Message;
        raise;
      end;
    end;
  finally
    TThread.Synchronize(nil,
      procedure
      begin
        SaveLog(Log);
      end);
    Log.Free;
  end;
end;

德尔福 10.2; 印地10.6.2; 网络类型:2G/GPRS

【问题讨论】:

  • ReadTimeout 被应用为每字节超时,因此如果您真的遇到超时,那么您的读取与客户端的发送不匹配,或者您的流量根本没有按预期到达。使用嗅探器仔细检查任一方式
  • @RemyLebeau 感谢您的评论,我会尝试的。代码的另一个小问题:当客户端正常断开连接时,避免“连接正常关闭”异常的正确方法是什么?
  • 异常并不总是错误;这是一个基本的。您不应将其视为错误。在那之后,我唯一可以添加的只是“文档”和“查找它”。这是一个反复出现的问题(我记得@RemyLebeau 对代码所做的关于这个问题的反复出现的评论)。检查ww2.indyproject.org/KB/index.html?whydoikeepgettingeidconnc.htmstackoverflow.com/questions/1085933/…
  • @Thorba:可以在 TIdTCPServer.OnException 事件处理程序中引发“正常关闭连接”而不会产生任何问题,但问题是它“有时”在我的 try/except 块中引发。正如“文档”所说:“......您的客户端已尝试读取或写入连接。”。但我在服务器端,读取连接时我不期望它。我可以在代码中忽略它,没问题,但不一致的行为对我来说是可疑的,因为“有时”在 try/except 块中会引发异常。
  • @hsn EIdConnClosedGracefully 是服务器端的正常行为,您不应该避免它。如果你抓住它,就不要记录它,但不要丢弃它。让它逃逸OnExecute 以便TIdTCPServer 可以处理它以正确清理调用线程(否则,您必须手动关闭连接)。您正在做正确的事情来重新raise 捕获的异常,这是首选操作。

标签: delphi tcp indy gprs


【解决方案1】:

在 Remy Lebeau 的指导下,我做了很多天的网络流量监控,发现问题是由于网络质量低下造成的,其中大小大于 100 字节的 TCP 段大部分时间都会丢失!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-19
    相关资源
    最近更新 更多