检索进程网络使用情况 [英] Retrieve process network usage

查看:31
本文介绍了检索进程网络使用情况的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何让进程发送/接收字节?首选的方法是用 C# 来做.

我对此进行了大量搜索,但没有找到任何简单的解决方案.一些解决方案建议在机器上安装 WinPCap 并使用此库.

就像这个人问的:但没有成功 - 因为并非每个进程都显示在此计数器下.我再次想知道资源监视器如何在不使用此计数器的情况下获取此信息...

解决方案

资源监视器使用 ETW - 幸运的是,微软已经创建了一个很好的 nuget .net 包装器 使其更易于使用.

我最近写了这样的东西来报告我进程的网络IO:

使用系统;使用 System.Diagnostics;使用 System.Threading.Tasks;使用 Microsoft.Diagnostics.Tracing.Parsers;使用 Microsoft.Diagnostics.Tracing.Session;命名空间进程监控{公共密封类 NetworkPerformanceReporter : IDisposable{私人日期时间 m_EtwStartTime;私人 TraceEventSession m_EtwSession;private readonly Counters m_Counters = new Counters();私人班柜台{公众号长期收到;公开长发;}私有 NetworkPerformanceReporter() { }公共静态 NetworkPerformanceReporter Create(){var networkPerformancePresenter = new NetworkPerformanceReporter();networkPerformancePresenter.Initialise();返回 networkPerformancePresenter;}私有无效初始化(){//请注意,ETW 类会阻止处理消息,因此如果您希望应用程序保持响应,则应在不同的线程上运行.Task.Run(() => StartEtwSession());}私有无效 StartEtwSession(){尝试{var processId = Process.GetCurrentProcess().Id;重置计数器();使用 (m_EtwSession = new TraceEventSession("MyKernelAndClrEventsSession")){m_EtwSession.EnableKernelProvider(KernelTraceEventParser.Keywords.NetworkTCPIP);m_EtwSession.Source.Kernel.TcpIpRecv += 数据 =>{if (data.ProcessID == processId){锁(m_Counters){m_Counters.Received += data.size;}}};m_EtwSession.Source.Kernel.TcpIpSend += 数据 =>{if (data.ProcessID == processId){锁(m_Counters){m_Counters.Sent += data.size;}}};m_EtwSession.Source.Process();}}抓住{重置计数器();//停止报告数字//可能应该记录异常}}公共网络性能数据 GetNetworkPerformanceData(){var timeDifferenceInSeconds = (DateTime.Now - m_EtwStartTime).TotalSeconds;NetworkPerformanceData 网络数据;锁(m_Counters){networkData = 新的 NetworkPerformanceData{BytesReceived = Convert.ToInt64(m_Counters.Received/timeDifferenceInSeconds),BytesSent = Convert.ToInt64(m_Counters.Sent/timeDifferenceInSeconds)};}//重置计数器以获得下次调用时的新读数.重置计数器();返回网络数据;}私有无效重置计数器(){锁(m_Counters){m_Counters.Sent = 0;m_Counters.Received = 0;}m_EtwStartTime = DateTime.Now;}公共无效处置(){m_EtwSession?.Dispose();}}公共密封类 NetworkPerformanceData{公共长字节接收{得到;放;}公共长字节发送{获取;放;}}}

How can I get a process send/receive bytes? the preferred way is doing it with C#.

I've searched this a lot and I didn't find any simple solution for this. Some solutions suggested to install the WinPCap on the machine and to work with this lib.

Like this guy asked: Need "Processes with Network Activity" functionality in managed code - Like resmon.exe does it I don't want the overhead of the lib.

Is there a simple solution for this? Actually I want the exactly data that the Resource Monitor of Windows gives under the "Processes with Network Activity" tab:

How does the Resource Monitor of Windows gets this information? Any example?

Also, tried to use the counter method which is mentioned over here: Missing network sent/received but with no success - as not every process is shown under this counter. And again I'm wondering how the Resource Monitor gets this information even without using this counter...

解决方案

Resource monitor uses ETW - thankfully, Microsoft have created a nice nuget .net wrapper to make it easier to use.

I wrote something like this recently to report back my process's network IO:

using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Microsoft.Diagnostics.Tracing.Parsers;
using Microsoft.Diagnostics.Tracing.Session;

namespace ProcessMonitoring
{
    public sealed class NetworkPerformanceReporter : IDisposable
    {
        private DateTime m_EtwStartTime;
        private TraceEventSession m_EtwSession;

        private readonly Counters m_Counters = new Counters();

        private class Counters
        {
            public long Received;
            public long Sent;
        }

        private NetworkPerformanceReporter() { }

        public static NetworkPerformanceReporter Create()
        {
            var networkPerformancePresenter = new NetworkPerformanceReporter();
            networkPerformancePresenter.Initialise();
            return networkPerformancePresenter;
        }

        private void Initialise()
        {
            // Note that the ETW class blocks processing messages, so should be run on a different thread if you want the application to remain responsive.
            Task.Run(() => StartEtwSession()); 
        }

        private void StartEtwSession()
        {
            try
            {
                var processId = Process.GetCurrentProcess().Id;
                ResetCounters();

                using (m_EtwSession = new TraceEventSession("MyKernelAndClrEventsSession"))
                {
                    m_EtwSession.EnableKernelProvider(KernelTraceEventParser.Keywords.NetworkTCPIP);

                    m_EtwSession.Source.Kernel.TcpIpRecv += data =>
                    {
                        if (data.ProcessID == processId)
                        {
                            lock (m_Counters)
                            {
                                m_Counters.Received += data.size;
                            }
                        }
                    };

                    m_EtwSession.Source.Kernel.TcpIpSend += data =>
                    {
                        if (data.ProcessID == processId)
                        {
                            lock (m_Counters)
                            {
                                m_Counters.Sent += data.size;
                            }
                        }
                    };

                    m_EtwSession.Source.Process();
                }
            }
            catch
            {
                ResetCounters(); // Stop reporting figures
                // Probably should log the exception
            }
        }

        public NetworkPerformanceData GetNetworkPerformanceData()
        {
            var timeDifferenceInSeconds = (DateTime.Now - m_EtwStartTime).TotalSeconds;

            NetworkPerformanceData networkData;

            lock (m_Counters)
            {
                networkData = new NetworkPerformanceData
                {
                    BytesReceived = Convert.ToInt64(m_Counters.Received / timeDifferenceInSeconds),
                    BytesSent = Convert.ToInt64(m_Counters.Sent / timeDifferenceInSeconds)
                };

            }

            // Reset the counters to get a fresh reading for next time this is called.
            ResetCounters();

            return networkData;
        }

        private void ResetCounters()
        {
            lock (m_Counters)
            {
                m_Counters.Sent = 0;
                m_Counters.Received = 0;
            }
            m_EtwStartTime = DateTime.Now;
        }

        public void Dispose()
        {
            m_EtwSession?.Dispose();
        }
    }

    public sealed class NetworkPerformanceData
    {
        public long BytesReceived { get; set; }
        public long BytesSent { get; set; }
    }
}

这篇关于检索进程网络使用情况的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆