web-dev-qa-db-ja.com

プロセスネットワークの使用状況を取得する

プロセスの送信/受信バイトを取得するにはどうすればよいですか?推奨される方法は、C#でそれを行うことです。

私はこれをたくさん検索しましたが、これに対する簡単な解決策は見つかりませんでした。いくつかの解決策は、マシンにWinPCapをインストールし、このライブラリを操作することを提案しました。

この男が尋ねたように: マネージコードに「ネットワークアクティビティのあるプロセス」機能が必要-resmon.exeのように ライブラリのオーバーヘッドは必要ありません。

これに対する簡単な解決策はありますか?実際、Windowsのリソースモニターが[ネットワークアクティビティのあるプロセス]タブで提供する正確なデータが必要です。enter image description here

Windowsのリソースモニターはどのようにしてこの情報を取得しますか?例はありますか?

また、ここで説明されているカウンターメソッドを使用しようとしました: ネットワークの送受信がありません しかし成功しませんでした-すべてのプロセスがこのカウンターの下に表示されるわけではないためです。また、このカウンターを使用しなくても、リソースモニターがこの情報を取得する方法について疑問に思っています...

21
Tomer Peled

リソースモニターは [〜#〜] etw [〜#〜] を使用します-ありがたいことに、Microsoftは使いやすくするためにNice nuget .netラッパー を作成しました。

最近、プロセスのネットワーク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; }
    }
}
13
Kram

PerformanceCounter を使用できます。サンプルコード:

//Define 
string pn = "MyProcessName.exe";
var readOpSec  = new PerformanceCounter("Process","IO Read Operations/sec", pn);
var writeOpSec = new PerformanceCounter("Process","IO Write Operations/sec", pn);
var dataOpSec  = new PerformanceCounter("Process","IO Data Operations/sec", pn);
var readBytesSec = new PerformanceCounter("Process","IO Read Bytes/sec", pn);
var writeByteSec = new PerformanceCounter("Process","IO Write Bytes/sec", pn);
var dataBytesSec = new PerformanceCounter("Process","IO Data Bytes/sec", pn);

var counters = new List<PerformanceCounter>
                {
                readOpSec,
                writeOpSec,
                dataOpSec,
                readBytesSec,
                writeByteSec,
                dataBytesSec
                };

// get current value
foreach (PerformanceCounter counter in counters)
{
    float rawValue = counter.NextValue();

    // display the value
}

そして、これはネットワークカードのパフォーマンスカウンターを取得することです。プロセス固有ではないことに注意してください

string cn = "get connection string from WMI";

var networkBytesSent = new PerformanceCounter("Network Interface", "Bytes Sent/sec", cn);
var networkBytesReceived = new PerformanceCounter("Network Interface", "Bytes Received/sec", cn);
var networkBytesTotal = new PerformanceCounter("Network Interface", "Bytes Total/sec", cn);

Counters.Add(networkBytesSent);
Counters.Add(networkBytesReceived);
Counters.Add(networkBytesTotal);
2
oleksii