【问题标题】:How to measure the TCP/IP overhead without sniffing?如何在不嗅探的情况下测量 TCP/IP 开销?
【发布时间】:2010-02-03 16:03:56
【问题描述】:

我想知道在通过 TCP 流发送数据时是否有一种编程方式来测量使用的全部带宽。由于我似乎不知道网络堆栈如何将流分成数据包,或者当它发送 TCP SYN 或 ACK 或它在后台为您执行的许多事情时,我只能对此进行粗略估计。

我能想到的唯一解决方案是实际嗅探接口,但我想认为堆栈已经可以为我收集这些统计信息。

这是在 Windows 或 Linux 下的 Java 中运行的(当然,首选可移植的解决方案),但我可以 JNI 化 C/C++ 答案,这样(和 OS API 调用)也是一个很好的答案。谢谢!

【问题讨论】:

  • 如果您询问可用于收集此信息的操作系统工具,这确实是一个服务器故障问题。
  • 不,我问的不是操作系统工具,我问的是可能收集此信息的 API。
  • 嗯,除了嗅探还有什么解决办法吗?我有一个收集音频/视频流的应用程序,如果知道由于网络拥塞和 TCP 开销而使用的确切带宽,我真的会受益匪浅。
  • 是的,我需要这个用于 .NET。
  • @Daniel:你需要问自己的问题。您可以使用指向此链接的链接并解释它的相似之处和不同之处(至少不同平台),但不要劫持。

标签: performance networking tcp measurement


【解决方案1】:

[Windows 特定答案]

在 Windows 上,您可以考虑查看 ETW(Windows 事件跟踪)。通常,ETW 是用于在 Windows 上提供跟踪/日志记录信息的技术,并且大多数 Microsoft 软件已经配备了您可以使用的 ETW 提供程序。在您的情况下,我认为 Microsoft-Windows-TCPIP 提供程序具有可能对您有所帮助的信息(例如本地/远程地址和端口、操作、发送/接收的字节数等)。

例如,我可以使用以下命令开始将 TCPIP 事件收集到文件中:

logman start MyTcpipLog -p Microsoft-Windows-TCPIP -ets

然后停止

logman stop MyTcpipLog -ets

然后可以使用许多不同的工具(例如 xperf)打开 MyTcipipLog.etl 文件,但您可以使用 API 自行解析此文件。

如果您想在运行时执行此操作,您可以创建一个"real-time" ETW session 来处理传入的事件。

如果您是 ETW 的新手,这里是我使用的 a helpful article on MSDN

【讨论】:

    【解决方案2】:

    不能代表 Windows,但从 2.6.37 开始,Linux 内核没有收集您正在寻找的统计信息。每个套接字的统计信息必须在 struct sock 或其后代中,我在那里看不到任何发送/接收计数器:

    http://lxr.linux.no/linux+v2.6.37.3/include/net/sock.h#L224

    【讨论】:

    • 其中一些导出到 /proc/net/tcp,请参阅 here。但是没有明确的计数器...
    【解决方案3】:

    在 Linux 上,这对于 root 来说是相当微不足道的信息(只需创建一个与您的流量匹配的 netfilter 链,您可以使用进程 id 匹配,例如,稍后读取与该链关联的计数器)。在有限的权限下这样做很可能是不可能的。

    不确定是否适用于 Windows。

    【讨论】:

      【解决方案4】:

      应该可以使用 conntrack 记帐来测量每个连接的数据包和字节。然后应该使用 netlink 套接字查询信息。使用 getsockname 和 getpeername 获取有关您的套接字的信息,并使用此信息查找连接跟踪条目。

      这需要足够新的内核、加载的 conntrack 模块和 libnetfilter_conntrack。

      此外,/proc/net/nf_conntrack 中提供了相同的信息,但该文件不应被过于频繁地解析。

      还有一个名为“conntrack”的工具,可让您从命令行访问这些信息。

      【讨论】:

        【解决方案5】:

        您可以考虑使用 Perfmon 计数器。网络接口/当前带宽计数器可能是您需要的。您可以从 .NET 代码创建和使用性能计数器。

        【解决方案6】:

        TCP 是由 MTU 指定的固定数据报。如果您知道您的 MTU,您就可以计算出您必须传输多少数据包,并且 TCP 遵循标准模型进行确认。

        Here is a good article 帮助计算数据传输的开销,其中包括以太网和堆栈的其他层的开销。

        【讨论】:

        • 嗯,不完全是。在您的 ssh 连接上运行 tcpdump - 所有段的大小是否相同?
        • 我应该澄清说有一个由 MTU 确定的最大段大小。如果应用程序希望发送的数据量超过由 MTU 确定的 MSS,则数据包将变为“碎片化”。但本质上,如果您知道一次要发送多少数据以及网络上的 MTU,您就可以计算出传输数据所需的总开销。
        • 是的......这将是最小可能的开销,而不是实际开销,这取决于应用程序如何随着时间的推移使用网络。假设我需要每分钟单向传输 40 个字节。忽略连接握手和拆除,我可能最终得到一个 80 字节的数据包(20 个用于 IPv4 标头,20 个用于没有选项的 TCP 标头,40 个用于数据)。这已经是 100% 的开销,甚至还没有计算返回的完全不携带应用程序数据的 ACK。
        • 尼古拉是正确的。我已经可以得到一个估计值(他说的最小可能开销),但我希望能够测量 TCP 整个 enchilada 所产生的实际开销。
        • MTU 在 TCP 中根本不可见,它是一个流套接字协议。你只需要确保你有足够的传输缓冲区。另外,关于TCP的答案海报也完全错误。就像装满水的水桶,装满一个有洞的水桶,接收到的信息慢慢倾泻而出。如果您在调用 recv() 时需要 X 字节的信息,您可能会得到一个数据包中的一些,以及其他几个数据包中的一些。我认为你应该停止传播错误信息并停止谈论明显超出你的话题。
        【解决方案7】:

        如果这个 TCP 流是唯一通过你的接口的东西,你可以只查询接口统计信息(发送/接收的字节数)并自己测量时间(+做数学)。

        【讨论】:

          猜你喜欢
          • 2013-10-01
          • 2013-05-02
          • 1970-01-01
          • 1970-01-01
          • 2011-02-26
          • 1970-01-01
          • 1970-01-01
          • 2010-10-10
          • 2011-03-29
          相关资源
          最近更新 更多