C++获取指定exe程序网络发送与接收速率

本教程将介绍如何使用C++和Windows API函数获取指定exe程序的网络发送和接收速率。

原理

我们将使用以下Windows API函数实现目标:

  1. GetTcpTable2:获取系统当前TCP连接表,包含每个TCP连接的详细信息,如本地地址、远程地址、进程ID等。
  2. GetProcessIdByName:根据进程名获取进程ID,用于筛选目标exe程序的TCP连接。
  3. GetPerTcpConnectionEStats:获取指定TCP连接的扩展统计信息,包括发送和接收字节数、时间戳等,用于计算网络速率。

代码实现

#include <winsock2.h>
#include <iphlpapi.h>
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <ws2tcpip.h>
#include <mstcpip.h>
#include <tlhelp32.h>
#pragma comment(lib, 'iphlpapi.lib')
#pragma comment(lib, 'ws2_32.lib')

DWORD GetProcessIdByName(const TCHAR* szProcessName)
{
    DWORD dwProcessId = 0;
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot != INVALID_HANDLE_VALUE)
    {
        PROCESSENTRY32 pe32;
        pe32.dwSize = sizeof(PROCESSENTRY32);
        if (Process32First(hSnapshot, &pe32))
        {
            do
            {
                if (_tcscmp(pe32.szExeFile, szProcessName) == 0)
                {
                    dwProcessId = pe32.th32ProcessID;
                    break;
                }
            } while (Process32Next(hSnapshot, &pe32));
        }
        CloseHandle(hSnapshot);
    }
    return dwProcessId;
}

void GetTcpConnectionStats(DWORD dwProcessId, MIB_TCPROW2 tcpRow)
{
    PMIB_TCPROW_OWNER_PID pTcpRowOwnerPid = (PMIB_TCPROW_OWNER_PID)&tcpRow;
    TCP_ESTATS_PATH_ROD_v0 PathStats;

    // 初始化PathStats结构体
    memset(&PathStats, 0, sizeof(PathStats));
    PathStats.EnableCollection = TRUE;

    // 获取TCP连接的发送与接收速率等信息
    if (GetPerTcpConnectionEStats(pTcpRowOwnerPid, TcpConnectionEstatsPath, NULL, 0, sizeof(PathStats), (PUCHAR)&PathStats, 0, 0) == NO_ERROR)
    {
        // 计算发送速率 (bytes/s)
        ULONGLONG ulSendSpeed = PathStats.DataBytesOut / PathStats.TimeStamp;
        // 计算接收速率 (bytes/s)
        ULONGLONG ulReceiveSpeed = PathStats.DataBytesIn / PathStats.TimeStamp;
        // TODO: 处理发送与接收速率
        printf('进程ID: %lu, 发送速率: %llu bytes/s, 接收速率: %llu bytes/s\n', dwProcessId, ulSendSpeed, ulReceiveSpeed);
    }
}

void GetTcpConnections(const TCHAR* szProcessName)
{
    MIB_TCPTABLE2* pTcpTable = NULL;
    DWORD dwSize = 0;

    // 获取TCP连接表大小
    if (GetTcpTable2(pTcpTable, &dwSize, TRUE) == ERROR_INSUFFICIENT_BUFFER)
    {
        // 分配内存
        pTcpTable = (MIB_TCPTABLE2*)malloc(dwSize);
        // 获取TCP连接表
        if (GetTcpTable2(pTcpTable, &dwSize, TRUE) == NO_ERROR)
        {
            // 获取目标进程ID
            DWORD dwTargetProcessId = GetProcessIdByName(szProcessName);
            // 遍历TCP连接
            for (DWORD i = 0; i < pTcpTable->dwNumEntries; i++)
            {
                MIB_TCPROW2 tcpRow = pTcpTable->table[i];
                // 获取进程ID
                DWORD dwProcessId = tcpRow.dwOwningPid;
                // 判断是否为目标进程
                if (dwProcessId == dwTargetProcessId)
                {
                    GetTcpConnectionStats(dwProcessId, tcpRow);
                }
            }
        }
        free(pTcpTable);
    }
}

int main()
{
    // 初始化Winsock
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    {
        printf('WSAStartup failed.\n');
        return 1;
    }

    GetTcpConnections(_T('目标exe名称.exe')); // 替换为实际的exe文件名

    // 清理Winsock
    WSACleanup();

    return 0;
}

注意

  • 以上代码仅获取TCP连接的网络速率,无法获取UDP连接的速率信息。
  • 获取到的速率是瞬时速率,可以定时调用GetTcpConnections函数并计算平均值来获得更稳定的速率值。
  • 在实际应用中,您可能需要根据具体需求对代码进行调整,例如添加错误处理机制、多线程支持等。

希望本教程能够帮助您使用C++获取指定exe程序的网络发送和接收速率。

C++获取指定exe程序网络发送与接收速率

原文地址: https://www.cveoy.top/t/topic/fSXn 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录