簡體   English   中英

如何在Windows下監控進程網絡使用情況

[英]How to monitor process network usage under windows

我正在尋找一種方法來獲取信息列表作為Windows下的資源監視器,如: 在此輸入圖像描述 我想知道所選應用程序的地址發送接收使用情況。

一開始我正在尋找一個c ++ win32 api或其他開源庫來做到這一點,我可以找到像GetProcessInformation這樣的東西,但它不包括網絡信息。

我看到了一些類似的話題,但他們沒有幫助。
Ref_001 ,似乎網絡監視器api無法做專用的監視器。
Ref_002 ,我不確定OpenTrace/ProcessTrace/StopTrace可以讓我獲得網絡使用,而且我也不確定如何使用它。
Ref_003 ,他們建議使用一些工具,但這不是我想要的。

Windows通過兩個部分為您提供這些信息,這些部分來自不同的功能,您需要將它們組合在一起以獲得完整的故事。 從技術上講,它有三個功能:對於數據的第二部分,IPv4和IPv6數據有單獨的功能。

第一個函數是GetExtendedTcpTable 要獲取上述所有信息,您可能需要調用此(至少)兩次:一次使用TCP_TABLE_OWNER_PID_CONNECTIONS標志,一次使用TCP_TABLE_OWNER_MODULE_CONNECTIONS標志來檢索PID和本地可執行文件的模塊名稱。

第二對可以獲取有關特定連接上發送/接收的數據的統計信息。 每個連接由本地地址/端口和遠程地址端口的組合標識(與上面使用的相同)。 使用GetPerTcpConnectionEStats for IPv4或GetPerTcp6ConnectionEStats for IPv6檢索信息。

其中任何一個都將檢索一個表,表中的每一行都包含一個連接的統計信息。 如果您(例如)在瀏覽器中打開了多個選項卡,則可以選擇單獨顯示每個連接的數據,也可以按照您認為合適的方式將它們合並。

感謝您的指導Jerry Coffin

這是我從這些庫中獲得的一些非常“POC”的代碼。 Spoiler alert - 剛剛在這里實現了TCPv4。 代碼引自

https://docs.microsoft.com/en-gb/windows/desktop/api/iphlpapi/nf-iphlpapi-getpertcpconnectionestats

請原諒hacky代碼的性質,但我認為發布比等待那個永遠不會到來的完美日子更好!

容器“NetworkPerformanceItem.h”的結果容器

#pragma once
#include "stdafx.h"
#include <string>
#include <windows.h>

class NetworkPerformanceItem
{
public:
    NetworkPerformanceItem();
    ~NetworkPerformanceItem();

    INT ProcessId;
    INT State;
    std::string LocalAddress;
    std::string RemoteAddress;
    int LocalPort;
    int RemotePort;
    LONG BytesOut;
    LONG BytesIn;
    LONG OutboundBandwidth;
    LONG InboundBandwidth;
    int Pass = 0;
    std::string CollectionTime;

};

標題“NetworkPerformanceScanner.h”

#pragma once
#include <iostream>
#include <vector>
#include <sstream>
#include "NetworkPerformanceItem.h"
#include <iomanip>
#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <iphlpapi.h>
#include <Tcpestats.h>
#include <stdlib.h>
#include <stdio.h>


using namespace std;

#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")

#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x)) 
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))

class NetworkPerformanceScanner
{
public:
    NetworkPerformanceScanner();
    ~NetworkPerformanceScanner();

    std::vector<NetworkPerformanceItem> ScanNetworkPerformance(int sampleId);
};

來源“NetworkPerformanceScanner.cpp”

#include "stdafx.h"
    #include "NetworkPerformanceScanner.h"



NetworkPerformanceScanner::NetworkPerformanceScanner()
{

}


NetworkPerformanceScanner::~NetworkPerformanceScanner()
{
}

// TODO - implement TCP v6, UDP
std::vector<NetworkPerformanceItem> NetworkPerformanceScanner::ScanNetworkPerformance(int pass)
{

    std::vector<unsigned char> buffer;
    DWORD dwSize = sizeof(MIB_TCPTABLE_OWNER_PID);
    DWORD dwRetValue = 0;
    vector<NetworkPerformanceItem> networkPerformanceItems;

    // get local computer time with timezone offset
    auto time = std::time(nullptr);
    std::ostringstream timeStream;
    timeStream << std::put_time(std::localtime(&time), "%F %T%z");
    string collectionTime = timeStream.str();

    // repeat till buffer is big enough
    do
    {
        buffer.resize(dwSize, 0);
        dwRetValue = GetExtendedTcpTable(buffer.data(), &dwSize, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);

    } while (dwRetValue == ERROR_INSUFFICIENT_BUFFER);

    if (dwRetValue == ERROR_SUCCESS)
    {
        // good case

        // cast to access element values
        PMIB_TCPTABLE_OWNER_PID ptTable = reinterpret_cast<PMIB_TCPTABLE_OWNER_PID>(buffer.data());

        cout << "Number of Entries: " << ptTable->dwNumEntries << endl << endl;


        // caution: array starts with index 0, count starts by 1
        for (DWORD i = 0; i < ptTable->dwNumEntries; i++)
        {
            NetworkPerformanceItem networkPerformanceItem;

            networkPerformanceItem.ProcessId = ptTable->table[i].dwOwningPid;
            networkPerformanceItem.State = ptTable->table[i].dwState;           

            cout << "PID: " << ptTable->table[i].dwOwningPid << endl;
            cout << "State: " << ptTable->table[i].dwState << endl;

            std::ostringstream localStream;
            localStream << (ptTable->table[i].dwLocalAddr & 0xFF)
                << "."
                << ((ptTable->table[i].dwLocalAddr >> 8) & 0xFF)
                << "."
                << ((ptTable->table[i].dwLocalAddr >> 16) & 0xFF)
                << "."
                << ((ptTable->table[i].dwLocalAddr >> 24) & 0xFF)
                << ":"
                << htons((unsigned short)ptTable->table[i].dwLocalPort);
            networkPerformanceItem.LocalAddress = localStream.str();
            networkPerformanceItem.LocalPort = ptTable->table[i].dwLocalPort;

            std::ostringstream remoteStream;
            remoteStream << (ptTable->table[i].dwRemoteAddr & 0xFF)
                << "."
                << ((ptTable->table[i].dwRemoteAddr >> 8) & 0xFF)
                << "."
                << ((ptTable->table[i].dwRemoteAddr >> 16) & 0xFF)
                << "."
                << ((ptTable->table[i].dwRemoteAddr >> 24) & 0xFF)
                << ":"
                << htons((unsigned short)ptTable->table[i].dwRemotePort);
            networkPerformanceItem.RemoteAddress = remoteStream.str();
            networkPerformanceItem.RemotePort = ptTable->table[i].dwRemotePort;

            MIB_TCPROW row;
            row.dwLocalAddr = ptTable->table[i].dwLocalAddr;
            row.dwLocalPort = ptTable->table[i].dwLocalPort;
            row.dwRemoteAddr = ptTable->table[i].dwRemoteAddr;
            row.dwRemotePort = ptTable->table[i].dwRemotePort;
            row.dwState = ptTable->table[i].dwState;
            void *processRow = &row;

            if (row.dwRemoteAddr != 0)
            {
                ULONG rosSize = 0, rodSize = 0;
                ULONG winStatus;
                PUCHAR ros = NULL, rod = NULL;
                rodSize = sizeof(TCP_ESTATS_DATA_ROD_v0);
                PTCP_ESTATS_DATA_ROD_v0 dataRod = { 0 };

                if (rosSize != 0) {
                    ros = (PUCHAR)malloc(rosSize);
                    if (ros == NULL) {
                        wprintf(L"\nOut of memory");
                        return networkPerformanceItems;
                    }
                    else
                        memset(ros, 0, rosSize); // zero the buffer
                }
                if (rodSize != 0) {
                    rod = (PUCHAR)malloc(rodSize);
                    if (rod == NULL) {
                        free(ros);
                        wprintf(L"\nOut of memory");
                        return networkPerformanceItems;
                    }
                    else
                        memset(rod, 0, rodSize); // zero the buffer
                }

                winStatus = GetPerTcpConnectionEStats((PMIB_TCPROW)&row, TcpConnectionEstatsData, NULL, 0, 0, ros, 0, rosSize, rod, 0, rodSize);

                dataRod = (PTCP_ESTATS_DATA_ROD_v0)rod;

                networkPerformanceItem.BytesIn = dataRod->DataBytesIn;
                networkPerformanceItem.BytesOut = dataRod->DataBytesOut;

                PTCP_ESTATS_BANDWIDTH_ROD_v0 bandwidthRod = { 0 };

                rodSize = sizeof(TCP_ESTATS_BANDWIDTH_ROD_v0);
                if (rodSize != 0) {
                    rod = (PUCHAR)malloc(rodSize);
                    if (rod == NULL) {
                        free(ros);
                        wprintf(L"\nOut of memory");
                        return networkPerformanceItems;
                    }
                    else
                        memset(rod, 0, rodSize); // zero the buffer
                }

                winStatus = GetPerTcpConnectionEStats((PMIB_TCPROW)&row,TcpConnectionEstatsBandwidth, NULL, 0, 0, ros, 0, rosSize, rod, 0, rodSize);

                bandwidthRod = (PTCP_ESTATS_BANDWIDTH_ROD_v0)rod;
                networkPerformanceItem.OutboundBandwidth = bandwidthRod->OutboundBandwidth;
                networkPerformanceItem.InboundBandwidth = bandwidthRod->InboundBandwidth;

            }
            networkPerformanceItem.Pass = pass;
            networkPerformanceItem.CollectionTime = collectionTime;
            networkPerformanceItems.push_back(networkPerformanceItem);
        }
    }
    else
    {
        // bad case, do some sh*t here
    }

    return networkPerformanceItems;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM