【问题标题】:Programmatically getting per-process network statistics on Windows?以编程方式获取 Windows 上的每个进程的网络统计信息?
【发布时间】:2010-10-12 10:21:01
【问题描述】:

我想知道哪些进程正在使用我的网络。这在 Linux 中很容易,但我不知道如何在 Windows 中做到这一点。

基本上,对于每个进程,我想知道它在一段时间内读取/写入网络的字节数。如果我能知道 IP 地址/端口号等,那就太好了。

有什么建议吗? Windows Vista/Windows 2008 似乎能够在资源监视器中执行此操作。他们是怎么做到的呢?开销是多少?

我想在我自己的代码中执行此操作,因此实用程序(TCPView、PerfMon)对我没有用处。我还希望有单独的磁盘和网络 I/O 计数器,所以默认的性能计数器是不够的。

Windows XP、2003、Vista、2008 和 7 为首选。 Win32 或 COM 都可以。

【问题讨论】:

  • 从目前的答案来看,似乎人们认为您正在寻找一个实用工具来执行此操作。您是在寻找工具,还是希望在自己的应用程序中自行编程?我建议澄清一下,如果合适的话,让我们知道你正在使用什么编程环境,等等。
  • 我在stackoverflow.com/questions/44689482/… 发布了一些 POC 代码以解决类似的问题。

标签: performance winapi networking


【解决方案1】:

经过大量研究,这是我想出的:

  1. 在各种论坛中有许多帖子要求提供相同的信息。
  2. 我看到的唯一可能编程解决方案是使用 Windows 事件跟踪 (ETW)。这需要一本小书来解释/理解。
  3. 可以从注册表中获取的 PERF 计数器对 Powershell 不友好。它们使用旨在供 C/C++ 程序使用的数据结构。一个非常完整的例子的 URL:http://msdn.microsoft.com/en-us/library/windows/desktop/aa372138(v=vs.85).aspx
  4. SysInternals 具有 TCPVIEW,可按进程显示网络使用情况。当您启动它时,大多数进程不会显示任何使用情况。它似乎只收集它正在运行的时间段的使用信息。这为使用 ETW 的想法提供了依据。
  5. 如果我用 IE9 浏览网站,我会看到 TCPVIEW 中正在创建进程。在大多数情况下,进程会在一分钟左右内消失(终止) - 以及进程的统计信息。
  6. 与 ProcessExplorer 类似,当创建进程时,它们会突出显示为绿色,而当它们被销毁时,它们会突出显示为红色。
  7. 红色突出显示的进程在下一次更新后消失。更新频率可以是 1、2 或 5 秒。但是有一个注册表设置,HKEY_CURRENT_USER\Software\Sysinternals\TCPView\Settings 可以修改以设置其他刷新频率。 If 是偏移量 0x98 处的 DWORD,以毫秒为单位。
  8. TCPVIEW 有一个“保存”/“另存为”菜单项。输出是一个空格分隔的文本文件,其中包含当前显示在 GUI 中的每个进程的使用情况统计信息。以下是文件中的示例行。行尾的数字是接收的 pkts/sec、接收的字节/秒、传输的 pkts/sec 和字节/秒,(不一定按此顺序) iexplore.exe 864 TCP tin 61207 a96-17-203-64.deploy.akamaitechnologies.com http ESTABLISHED 2 12,928 8 9,420

所以...

一个可能的解决方案是使用 TCPVIEW 并通过从脚本以编程方式生成的击键来控制它。您可以将刷新间隔设置为 1、10、30 等分钟,并让脚本发送击键以使 TCPVIEW 将输出保存在文件中。您可能希望脚本以刷新间隔的一半或三分之一发送击键,以确保您获得的快照至少与刷新间隔的 1/2 或 2/3 一样长。您可以使用 Import-CSV 导入文件,并在脚本中轻松操作。

或者……

你可能会变得自虐并使用 ETW。

或者……

您可以深入研究并将 Linux 的 proc 文件系统(正如您所指出的,从脚本中更容易使用)移植到 Windows :-)

【讨论】:

    【解决方案2】:

    我为此写了一个解决方案。

    用于收集统计信息的 TDI 过滤器驱动程序,该服务与驱动程序通信并每秒获取一次统计信息。由于过滤器在 TDI 层,我知道哪些套接字属于哪些应用程序。该服务是这些数据的服务器,通过我编写的 API 通过共享内存将其提供给任意第三方客户端。我写了一个 GUI 和一个命令行客户端。

    您还可以在窗口中实时调整发送带宽(每个接口和/或应用程序和/或套接字)并观察通过套接字传递的数据。

    【讨论】:

    • 我相信你的话,你看到了这个问题并决定“编写自定义 TDI 过滤器驱动程序”是最好的解决方案。我假设如果你有一些你可以发布的代码,你就会这样做,而且我不是那些说“向 m3 展示 c0deZ!”的人之一。为我指明正确的方向就足够了,谢谢。
    【解决方案3】:

    您将需要使用 IPHelper API。

    这是一篇很好的文章,详细介绍了它在 .NET 中的使用: http://www.codeproject.com/KB/IP/iphlpapi.aspx

    享受吧。

    【讨论】:

    • 这似乎不包含每个进程的统计信息。
    • 否,但它确实将进程链接到网络连接。这是难题之一。
    • 一些细节将不胜感激。
    • 它也只显示连接,而不是这些连接的吞吐量。
    【解决方案4】:

    你会惊讶于你可以从 Perfmon 中获得的东西。

    打开它,右键单击图形区域,然后选择“添加计数器...”。到处冲浪,看看有没有什么能满足你的需求。

    根据我对您所问内容的阅读,我会选择“进程”作为我的性能对象,并开始从进程列表中选择看起来可能是罪魁祸首,可能会监视“IO 数据字节/秒”计数器。如果你在那里乱来,你可能会发现一些对你更有用的东西。

    编辑: 我注意到它说“以编程方式”(昨天是这样说的吗?)

    嗯,您实际上可以使用键 HKEY_PERFORMANCE_DATA 从注册表中获取 Perfmon 获取的几乎所有信息。我认为这就是 Perfmon 枚举和使用的内容,因此您应该能够使用 perfmon 来查看其中的内容并为您工作,然后编写代码以在您自己的程序中实时读取它。

    这种方法的一大优点是,如果你有合适的权限,它甚至可以远程工作。

    【讨论】:

    • -1:perfom 中的 IO 字节将磁盘和网络 IO 汇总在一起。
    • 确实如此。但是,如果您没有运行任何有理由进行大量磁盘 I/O 的操作,那么它应该会为您做得很好。
    【解决方案5】:

    将 ETW 与 EVENT_TRACE_FLAG_NETWORK_TCPIP 一起使用即可。

    【讨论】:

      猜你喜欢
      • 2010-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-06
      • 2010-10-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-25
      相关资源
      最近更新 更多