获取网络进程生成的接收和发送字节 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/sec
和 IO Read Bytes/sec
显示 I/O 读取和写入字节而不是 'Send and Received Bytes'。
PS: I/O 计算进程生成的所有文件、网络和设备 I/Os 字节。但是,我只想要特定进程生成的网络字节。
我只想检索接收的字节数和发送的字节数。但是,不知道使用什么计数器来获取进程的这些字节。
我为此目的搜索了这些链接,但没有用:
- C# Resource Monitor get network activity values
- Retrieve process network usage
- Missing network sent/received
- Need "Processes with Network Activity" functionality in managed code - Like resmon.exe does it
这是尝试过的进程的性能计数器代码:
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 流量,您需要订阅 UdpIpSend
和 UdpIpRecv
事件。
这是我之前
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/sec
和 IO Read Bytes/sec
显示 I/O 读取和写入字节而不是 'Send and Received Bytes'。
PS: I/O 计算进程生成的所有文件、网络和设备 I/Os 字节。但是,我只想要特定进程生成的网络字节。
我只想检索接收的字节数和发送的字节数。但是,不知道使用什么计数器来获取进程的这些字节。
我为此目的搜索了这些链接,但没有用:
- C# Resource Monitor get network activity values
- Retrieve process network usage
- Missing network sent/received
- Need "Processes with Network Activity" functionality in managed code - Like resmon.exe does it
这是尝试过的进程的性能计数器代码:
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 流量,您需要订阅 UdpIpSend
和 UdpIpRecv
事件。