【问题标题】:Measuring network traffic with Indy使用 Indy 测量网络流量
【发布时间】:2010-10-08 07:15:32
【问题描述】:

我正在使用 TIdTCPCmdServer 来处理与客户端应用程序的所有通信。我希望我的服务器记录所有类型的东西,包括网络流量。有没有简单或聪明的方法来查看 TCPCmdServer 实际接收和发送了多少字节?我只能想到类似的代码

ASender.SendReply;
Inc (FTraffic, Sizeof (ASender.NormalReply.Code) +
               Sizeof (Char) * ASender.NormalReply.Text.Length));

在我看来这非常难看,因为这些流量更新会分散在我的代码中,而且相当复杂。

有什么建议吗?

感谢您的帮助。

【问题讨论】:

    标签: delphi networking client-server indy


    【解决方案1】:

    查看 Indy 的拦截类。您应该能够创建一个覆盖 Receive() 和 Send() 方法的自定义拦截类,并且除了调用基类的方法之外,还可以实现您的流量计算。已经有拦截类来做日志记录,你可以用同样的方式连接你的自定义类。

    TIdConnectionIntercept 的文档应该是一个很好的起点。还有一个非常简单的例子here,关于如何在运行时创建和连接拦截。

    【讨论】:

    • +1 谢谢!我按照你的建议实现了它,并用一些源代码添加了一个新的答案
    【解决方案2】:

    TCPCmdServer 包装到记录流量的类中。

    您可以从 TCPCmdServer 派生您的类并覆盖发送和接收方法(如果它们是虚拟的)。

    类似:

    type
      TTcpCmdServerWithLogging = class(TTcpCmdServer)
        ...
        procedure SendReply; override;
    
    implementation
        procedure SendReply;
        begin
          inherited SendReply;
          Inc (FTraffic, Sizeof (NormalReply.Code) +
               Sizeof (Char) * NormalReply.Text.Length)); 
        end;
    

    如果它们不是虚拟的,则创建实例化 TCPCmdServer 的新类并公开所需的方法和属性。

    【讨论】:

      【解决方案3】:

      非常感谢两位的回答。我选择按照 mghie 描述的方式来实现它——通过为我的连接实现一个自定义拦截器类。仅针对那些对解决方案感兴趣的人,我将在此处提供一些源代码:

      type
        TCountTrafficInterceptor = class (TIdConnectionIntercept)
        public
          type TIntPointer = ^Longint;
        private
          FTraffic : TIntPointer;
        public
          constructor Create (TrafficVar : TIntPointer);
          procedure Send (var ABuffer : TIdBytes); override;
          procedure Receive (var ABuffer : TIdBytes); override;
        end;
      
      constructor TCountTrafficInterceptor.Create (TrafficVar : TIntPointer);
      begin
        FTraffic := TrafficVar;
      end;
      
      procedure TCountTrafficInterceptor.Send (var ABuffer : TIdBytes);
      begin
        inherited Send (ABuffer);
        FTraffic^ := FTraffic^ + Length (ABuffer);
      end;
      
      procedure TCountTrafficInterceptor.Receive (var ABuffer : TIdBytes);
      begin
        inherited Receive (ABuffer);
        FTraffic^ := FTraffic^ + Length (ABuffer);
      end;
      

      并且在 TIdTCPCmdServer 的 OnConnect 方法中:

      AContext.Connection.IOHandler.Intercept := 
        TCountTrafficInterceptor.Create (@FNetworkTraffic);
      

      效果很好,正是我正在寻找的那种解决方案。再次感谢您的回答。

      顺便说一句:我如何在我的帖子中使用 (at) 符号?当我尝试输入时,我总是得到一个块引用...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多