获取网络进程生成的接收和发送字节 Activity

Getting Received and Sent Bytes generated by Process for Network Activity

这是我之前 的下一步。


I'm creating a C# WinForm Application which will display Network Activity (Bytes Received / Bytes Sent) for a given Process (For Example: Process name 's chrome.exe) and Speed in Megabits/s generated by the Process.

虽然使用性能计数器 IO Read Bytes/secIO Read Bytes/sec 显示 I/O 读取和写入字节而不是 'Send and Received Bytes'

PS: I/O 计算进程生成的所有文件、网络和设备 I/Os 字节。但是,我只想要特定进程生成的网络字节。

我只想检索接收的字节数和发送的字节数。但是,不知道使用什么计数器来获取进程的这些字节。

我为此目的搜索了这些链接,但没有用:

这是尝试过的进程的性能计数器代码:

PerformanceCounter bytesReceived = new PerformanceCounter("Process", "IO Read Bytes/sec");
PerformanceCounter bytesSent = new PerformanceCounter("Process", "IO Write Bytes/sec");
string ProcessName = "chrome";
bytesReceived.InstanceName = ProcessName;
bytesSent.InstanceName = ProcessName;

问题:如何只能获取网络进程生成的接收和发送字节activity。

正如评论中已经提到的那样,我认为没有办法使用 PerformanceCounter class 来实现这一点。由于它使用 Windows' 内置性能计数器,这可以通过使用网络 send/receive 的 typeperf command. On my local machine this yields about 3.200 different counters, which I went through to verify my claim. There actually are 计数器查询已安装计数器的整个列表来验证(即使对于特定网络 interfaces/adapters 或处理器),但其中 none 可以过滤特定进程或进程系列。


因此,更简单的方法可能是使用 this (already quite complete) answer, which makes use of the Microsoft.Diagnostics.Tracing.TraceEvent NuGet 包。为了进行测试,我将其压缩为最少量的代码并对其进行了修改以捕获整个进程系列的流量。

static void Main(string[] args)
{
    // Counter variables
    var counterLock = new object();
    int received = 0;
    int sent = 0;

    // Fetch ID of all Firefox processes
    var processList = Process.GetProcessesByName("firefox").Select(p => p.Id).ToHashSet();

    // Run in another thread, since this will be a blocking operation (see below)
    Task.Run(() =>
    {
        // Start ETW session
        using(var session = new TraceEventSession("MyKernelAndClrEventsSession"))
        {
            // Query network events
            session.EnableKernelProvider(KernelTraceEventParser.Keywords.NetworkTCPIP);

            // Subscribe to trace events
            // These will be called by another thread, so locking is needed here
            session.Source.Kernel.TcpIpRecv += data =>
            {
                if(processList.Contains(data.ProcessID))
                    lock(counterLock)
                        received += data.size;
            };
            session.Source.Kernel.TcpIpSend += data =>
            {
                if(processList.Contains(data.ProcessID))
                    lock(counterLock)
                        sent += data.size;
            };

            // Process all events (this will block)
            session.Source.Process();
        }
    });

    // Program logic to handle counter values
    while(true)
    {
        // Wait some time and print current counter status
        Task.Delay(2000).Wait();
        lock(counterLock)
            Console.WriteLine($"Sent: {sent.ToString("N0")} bytes    Received: {received.ToString("N0")} bytes");
    }
}

请注意,您需要提升(管理员)权限才能执行此代码。

我使用 Mozilla Firefox 进行了测试,当时它有 10 个进程(7 个选项卡)运行;我下载了一个大文件,程序正确打印了增加的网络流量(加上来自活动选项卡的一些噪音),不包括涉及的磁盘访问(这至少会使测量的流量增加一倍)。

另请注意,这只会捕获 TCP/IP 流量;要同时捕获 UDP/IP 流量,您需要订阅 UdpIpSendUdpIpRecv 事件。