如何在不嗅探的情况下测量 TCP/IP 开销?
我想知道是否有一种编程方式来获取通过 TCP 流发送数据时所使用的全部带宽的测量值。由于我似乎无法知道网络堆栈如何将流划分为数据包,或者何时发送 TCP SYN 或 ACK 或它在后台为您执行的许多操作,因此我只能对此进行粗略估计。
我能想到的唯一解决方案是实际嗅探接口,但我想堆栈已经可以为我收集这些统计信息。
这是在 Windows 或 Linux 下用 Java 运行的(当然,首选便携式解决方案),但我可以 JNI 化 C/C++ 答案,这样(以及操作系统 API 调用)也是一个很好的答案。谢谢你!
I'm wondering whether there is a programmatic way to obtain a measure of the full bandwidth used when sending data through a TCP stream. Since I cannot seem to know how the network stack would divide the stream into packets, or when it sends a TCP SYN or ACK or many of the things it does in the background for you, I can only get a rough estimate for this.
The only solution I can think of is to actually sniff the interface, but I would like to think that the stack can already collect this stats for me.
This is running in Java under either Windows or Linux (of course, a portable solution would be preferred), but I can JNI-ize a C/C++ answer so that (and OS API calls) is a fine answer too. Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
如果此 TCP 流是通过您的接口的唯一流,您只需查询接口统计信息(发送/接收的字节数)并自行测量时间(+进行数学计算)。
If this TCP stream is the only thing going through your interface, you could just query the interface statistics (bytes sent/received) and measure the time yourself (+do the math).
[Windows 特定答案]
在 Windows 上,您可以考虑查看 ETW(Windows 事件跟踪)。一般来说,ETW 是用于在 Windows 上提供跟踪/日志记录信息的技术,并且大多数 Microsoft 软件已经配备了您可以使用的 ETW 提供程序。就您而言,我认为 Microsoft-Windows-TCPIP 提供程序具有可能对您有帮助的信息(例如本地/远程地址和端口、操作、发送/接收的字节等)。
例如,我可以使用以下命令开始将 TCPIP 事件收集到文件中:
logman start MyTcpipLog -p Microsoft-Windows-TCPIP -ets
并使用
logman stop MyTcpipLog -ets 停止/code>
然后,可以使用许多不同的工具(例如 xperf)打开 MyTcipipLog.etl 文件,但您可以使用一些 API 自己解析该文件。
如果您想在运行时执行此操作,可以创建一个 “实时”ETW 会话,用于处理传入的事件。
如果您是 ETW 新手,请参阅我使用过的 MSDN 上的一篇有用文章。
[Windows specific answer]
On Windows you can consider looking at ETW (Event Tracing for Windows). In general, ETW is the technology used to provide tracing/logging information on Windows, and most Microsoft software is already instrumented with ETW providers that you can use. In your case, I think the Microsoft-Windows-TCPIP provider has information (e.g. local/remote address and port, operation, bytes sent/received, etc) that might be helpful for you.
For example, I was able to start collecting the TCPIP events to a file using the command:
logman start MyTcpipLog -p Microsoft-Windows-TCPIP -ets
And stop with
logman stop MyTcpipLog -ets
Then the MyTcipipLog.etl file can be opened using a number of different tools (e.g. xperf), but there are APIs that you can use to parse this file yourself.
If you wanted to be doing this at runtime, you can create a "real-time" ETW session to process the events as they come in.
If you're new to ETW, here's a helpful article on MSDN that I used.
不能代表 Windows,但从 2.6.37 开始,Linux 内核并没有收集您正在寻找的统计信息。每个套接字的统计信息必须位于 struct sock 或其后代中,并且我在那里没有看到任何传输/接收计数器:
http://lxr.linux.no/linux+v2.6.37.3/include/net/sock.h#L224< /a>
Can't speak for Windows, but the Linux kernel, as of 2.6.37, is not collecting the statistics you are looking for. Per-socket stats would have to be in struct sock or its descendants and I am not seeing any transmit/receive counters there:
http://lxr.linux.no/linux+v2.6.37.3/include/net/sock.h#L224
在 Linux 上,对于 root 来说,这是相当简单的信息(只需创建一个与您的流量匹配的 netfilter 链,您可以使用进程 ID 匹配,例如,稍后读取与该链关联的计数器)。在有限的权限下执行此操作很可能是不可能的。
不确定是否适用于 Windows。
On Linux, this is fairly trivial information for root to get (simply create a netfilter chain matching your traffic, you can use a process id match, for example, later read the counters associated with the chain). Doing it with limited permissions may well be impossible.
Not sure for Windows.
应该可以使用 conntrack 记帐来测量每个连接的数据包和字节。然后应该使用 netlink 套接字查询信息。使用 getsockname 和 getpeername 获取有关您的套接字的信息,并使用此信息查找连接跟踪条目。
这需要足够新的内核、加载的 conntrack 模块和 libnetfilter_conntrack。
此外,/proc/net/nf_conntrack 中提供了相同的信息,但不应过于频繁地解析该文件。
还有一个名为“conntrack”的工具,可以让您从命令行访问此信息。
It should be possible to use conntrack accounting to measure packets and bytes on a per connection basis. Then the information should be queried using netlink sockets. Get the information about your socket with getsockname and getpeername, and use this information to look up the connection tracking entry.
This requires recent enough kernel, conntrack module loaded and libnetfilter_conntrack.
Also, the same information is available in /proc/net/nf_conntrack, but that file shouldn't be parsed too frequently.
And there's a tool named "conntrack" that gives you access to this information from the command line.
您可以考虑使用 Perfmon 计数器。网络接口/当前带宽计数器可能正是您所需要的。您可以从 .NET 代码创建和使用性能计数器。
You could look into consuming Perfmon counters. The Network Interface/Current Bandwidth counter might be what you need. You can create and consume performance counters from .NET code.
TCP 是由 MTU 指定的固定数据报。如果您知道 MTU,则可以算出必须传输多少数据报,并且 TCP 遵循标准确认模型。
这是一篇很好的文章,有助于计算数据传输的开销,其中包括以太网和堆栈其他层的开销。
Well TCP is a fixed data gram which is specified by the MTU. If you know your MTU, you can figure out how many data grams you have to transmit and TCP follows a standard model for acknowledgment.
Here is a good article on that help figure out the overhead of data transmission, which includes the overhead of Ethernet and the other layers of the stack.