windows tcpview 类似功能 c++

// ============================================================

// FastNetworkMonitor.cpp

// Based on GetExtendedTcpTable - Ultra-fast network monitoring

// No Chinese characters - pure English version

// ============================================================

#include <winsock2.h>

#include <iphlpapi.h>

#include <stdio.h>

#include <windows.h>

#include <psapi.h>

#include <vector>

#include <string>

#include <algorithm>

#include <map>

#include <chrono>

#include <ctime>

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

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

#pragma comment(lib, "psapi.lib")

#pragma comment(lib, "kernel32.lib")

using namespace std;

using namespace std::chrono;

// ============================================================

// Constants

// ============================================================

#ifndef AF_INET

#define AF_INET 2

#endif

#ifndef TCP_TABLE_OWNER_PID_ALL

#define TCP_TABLE_OWNER_PID_ALL 5

#endif

#ifndef TCP_TABLE_OWNER_PID_LISTENER

#define TCP_TABLE_OWNER_PID_LISTENER 4

#endif

#ifndef UDP_TABLE_OWNER_PID

#define UDP_TABLE_OWNER_PID 1

#endif

// TCP states

#define MY_TCP_STATE_CLOSED 1

#define MY_TCP_STATE_LISTEN 2

#define MY_TCP_STATE_SYN_SENT 3

#define MY_TCP_STATE_SYN_RCVD 4

#define MY_TCP_STATE_ESTAB 5

#define MY_TCP_STATE_FIN_WAIT1 6

#define MY_TCP_STATE_FIN_WAIT2 7

#define MY_TCP_STATE_CLOSE_WAIT 8

#define MY_TCP_STATE_CLOSING 9

#define MY_TCP_STATE_TIME_WAIT 10

#define MY_TCP_STATE_DELETE_TCB 11

// ============================================================

// Data Structures

// ============================================================

struct NetworkConnection {

string Protocol;

string LocalAddr;

DWORD LocalPort;

string RemoteAddr;

DWORD RemotePort;

string State;

DWORD PID;

string ProcessName;

long long Timestamp;

string GetKey() const {

char buffer[512];

sprintf_s(buffer, sizeof(buffer), "%s|%s:%lu|%s:%lu",

Protocol.c_str(), LocalAddr.c_str(), LocalPort,

RemoteAddr.c_str(), RemotePort);

return string(buffer);

}

};

// ============================================================

// Global Variables

// ============================================================

map<string, NetworkConnection> g_previousConnections;

long long g_eventCount = 0;

long long g_pollCount = 0;

// ============================================================

// Windows API Declarations

// ============================================================

typedef int (WINAPI* PGetExtendedTcpTable)(

PVOID pTcpTable,

PDWORD pdwSize,

BOOL bOrder,

ULONG ulAf,

ULONG TableClass,

ULONG Reserved

);

typedef int (WINAPI* PGetExtendedUdpTable)(

PVOID pUdpTable,

PDWORD pdwSize,

BOOL bOrder,

ULONG ulAf,

ULONG TableClass,

ULONG Reserved

);

static PGetExtendedTcpTable pGetExtendedTcpTable = NULL;

static PGetExtendedUdpTable pGetExtendedUdpTable = NULL;

// Initialize API function pointers

void InitializeAPIFunctions() {

HMODULE hIphlpapi = LoadLibraryA("iphlpapi.dll");

if (hIphlpapi) {

pGetExtendedTcpTable = (PGetExtendedTcpTable)GetProcAddress(

hIphlpapi, "GetExtendedTcpTable");

pGetExtendedUdpTable = (PGetExtendedUdpTable)GetProcAddress(

hIphlpapi, "GetExtendedUdpTable");

}

}

// ============================================================

// Utility Functions

// ============================================================

string FormatIPAddress(DWORD ipAddr) {

unsigned char* bytes = (unsigned char*)&ipAddr;

char buffer[16];

sprintf_s(buffer, sizeof(buffer), "%u.%u.%u.%u",

bytes[0], bytes[1], bytes[2], bytes[3]);

return string(buffer);

}

string GetTcpStateName(DWORD state) {

switch (state) {

case MY_TCP_STATE_CLOSED: return "CLOSED";

case MY_TCP_STATE_LISTEN: return "LISTEN";

case MY_TCP_STATE_SYN_SENT: return "SYN_SENT";

case MY_TCP_STATE_SYN_RCVD: return "SYN_RCVD";

case MY_TCP_STATE_ESTAB: return "ESTAB";

case MY_TCP_STATE_FIN_WAIT1: return "FIN_WAIT1";

case MY_TCP_STATE_FIN_WAIT2: return "FIN_WAIT2";

case MY_TCP_STATE_CLOSE_WAIT: return "CLOSE_WAIT";

case MY_TCP_STATE_CLOSING: return "CLOSING";

case MY_TCP_STATE_TIME_WAIT: return "TIME_WAIT";

case MY_TCP_STATE_DELETE_TCB: return "DELETE_TCB";

default: {

static char buffer[32];

sprintf_s(buffer, sizeof(buffer), "STATE_%lu", state);

return string(buffer);

}

}

}

string GetCurrentTimeString() {

time_t now = time(0);

struct tm timeinfo;

localtime_s(&timeinfo, &now);

char buffer[16];

strftime(buffer, sizeof(buffer), "%H:%M:%S", &timeinfo);

return string(buffer);

}

/*

string GetProcessName(DWORD processId) {

if (processId == 0) return "System";

if (processId == 4) return "System";

HANDLE hProcess = OpenProcess(

PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,

FALSE,

processId

);

if (!hProcess) {

char buffer[32];

sprintf_s(buffer, sizeof(buffer), "PID:%lu", processId);

return string(buffer);

}

WCHAR szProcessName[MAX_PATH] = L"Unknown";

DWORD cbNeeded = 0;

HMODULE hMods[1024];

if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) {

GetModuleBaseNameW(hProcess, hMods[0], szProcessName,

sizeof(szProcessName) / sizeof(WCHAR));

}

char buffer[MAX_PATH];

WideCharToMultiByte(CP_ACP, 0, szProcessName, -1, buffer, MAX_PATH, NULL, NULL);

CloseHandle(hProcess);

return string(buffer);

}

*/

string GetProcessName(DWORD processId) {

if (processId == 0 || processId == 4) return "System";

HANDLE hProcess = OpenProcess(

PROCESS_QUERY_LIMITED_INFORMATION, // 权限降低,无需 VM_READ

FALSE,

processId

);

if (!hProcess) {

char buffer[32];

sprintf_s(buffer, sizeof(buffer), "PID:%lu", processId);

return string(buffer);

}

WCHAR szProcessName[MAX_PATH] = L"Unknown";

DWORD dwSize = MAX_PATH;

// 用 QueryFullProcessImageNameW 替代 EnumProcessModules + GetModuleBaseNameW

// 只需 PROCESS_QUERY_LIMITED_INFORMATION,不需要 VM_READ

QueryFullProcessImageNameW(hProcess, 0, szProcessName, &dwSize);

// 只取文件名部分,去掉路径

WCHAR* pName = wcsrchr(szProcessName, L'\\');

if (pName) pName++;

else pName = szProcessName;

char buffer[MAX_PATH];

WideCharToMultiByte(CP_ACP, 0, pName, -1, buffer, MAX_PATH, NULL, NULL);

CloseHandle(hProcess);

return string(buffer);

}

long long GetMemoryUsageMB() {

PROCESS_MEMORY_COUNTERS pmc;

if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) {

return pmc.WorkingSetSize / (1024 * 1024);

}

return 0;

}

// ============================================================

// Get Network Connections

// ============================================================

vector<NetworkConnection> GetTcpConnections() {

vector<NetworkConnection> connections;

if (!pGetExtendedTcpTable) {

printf("ERROR: GetExtendedTcpTable not initialized\n");

return connections;

}

DWORD dwSize = 0;

DWORD dwRetVal = 0;

// First call: get required buffer size

dwRetVal = pGetExtendedTcpTable(

NULL,

&dwSize,

FALSE,

AF_INET,

TCP_TABLE_OWNER_PID_ALL,

0

);

if (dwRetVal != ERROR_INSUFFICIENT_BUFFER) {

return connections;

}

// Allocate buffer

PMIB_TCPTABLE_OWNER_PID pTcpTable =

(PMIB_TCPTABLE_OWNER_PID)malloc(dwSize);

if (pTcpTable == NULL) {

return connections;

}

// Second call: get TCP table

dwRetVal = pGetExtendedTcpTable(

(PVOID)pTcpTable,

&dwSize,

FALSE,

AF_INET,

TCP_TABLE_OWNER_PID_ALL,

0

);

if (dwRetVal == NO_ERROR) {

for (DWORD i = 0; i < pTcpTable->dwNumEntries; i++) {

MIB_TCPROW_OWNER_PID row = pTcpTable->table[i];

NetworkConnection conn;

conn.Protocol = "TCP";

conn.LocalAddr = FormatIPAddress(row.dwLocalAddr);

conn.LocalPort = ntohs((unsigned short)row.dwLocalPort);

conn.RemoteAddr = FormatIPAddress(row.dwRemoteAddr);

conn.RemotePort = ntohs((unsigned short)row.dwRemotePort);

conn.State = GetTcpStateName(row.dwState);

conn.PID = row.dwOwningPid;

conn.ProcessName = GetProcessName(row.dwOwningPid);

conn.Timestamp = (long long)time(0);

connections.push_back(conn);

}

}

free(pTcpTable);

return connections;

}

vector<NetworkConnection> GetUdpConnections() {

vector<NetworkConnection> connections;

if (!pGetExtendedUdpTable) {

printf("ERROR: GetExtendedUdpTable not initialized\n");

return connections;

}

DWORD dwSize = 0;

DWORD dwRetVal = 0;

// First call: get required buffer size

dwRetVal = pGetExtendedUdpTable(

NULL,

&dwSize,

FALSE,

AF_INET,

UDP_TABLE_OWNER_PID,

0

);

if (dwRetVal != ERROR_INSUFFICIENT_BUFFER) {

return connections;

}

// Allocate buffer

PMIB_UDPTABLE_OWNER_PID pUdpTable =

(PMIB_UDPTABLE_OWNER_PID)malloc(dwSize);

if (pUdpTable == NULL) {

return connections;

}

// Second call: get UDP table

dwRetVal = pGetExtendedUdpTable(

(PVOID)pUdpTable,

&dwSize,

FALSE,

AF_INET,

UDP_TABLE_OWNER_PID,

0

);

if (dwRetVal == NO_ERROR) {

for (DWORD i = 0; i < pUdpTable->dwNumEntries; i++) {

MIB_UDPROW_OWNER_PID row = pUdpTable->table[i];

NetworkConnection conn;

conn.Protocol = "UDP";

conn.LocalAddr = FormatIPAddress(row.dwLocalAddr);

conn.LocalPort = ntohs((unsigned short)row.dwLocalPort);

conn.RemoteAddr = "0.0.0.0";

conn.RemotePort = 0;

conn.State = "BOUND";

conn.PID = row.dwOwningPid;

conn.ProcessName = GetProcessName(row.dwOwningPid);

conn.Timestamp = (long long)time(0);

connections.push_back(conn);

}

}

free(pUdpTable);

return connections;

}

vector<NetworkConnection> GetTcpListeners() {

vector<NetworkConnection> connections;

if (!pGetExtendedTcpTable) {

return connections;

}

DWORD dwSize = 0;

DWORD dwRetVal = 0;

dwRetVal = pGetExtendedTcpTable(

NULL,

&dwSize,

FALSE,

AF_INET,

TCP_TABLE_OWNER_PID_LISTENER,

0

);

if (dwRetVal != ERROR_INSUFFICIENT_BUFFER) {

return connections;

}

PMIB_TCPTABLE_OWNER_PID pTcpTable =

(PMIB_TCPTABLE_OWNER_PID)malloc(dwSize);

if (pTcpTable == NULL) {

return connections;

}

dwRetVal = pGetExtendedTcpTable(

(PVOID)pTcpTable,

&dwSize,

FALSE,

AF_INET,

TCP_TABLE_OWNER_PID_LISTENER,

0

);

if (dwRetVal == NO_ERROR) {

for (DWORD i = 0; i < pTcpTable->dwNumEntries; i++) {

MIB_TCPROW_OWNER_PID row = pTcpTable->table[i];

NetworkConnection conn;

conn.Protocol = "TCP_LISTEN";

conn.LocalAddr = FormatIPAddress(row.dwLocalAddr);

conn.LocalPort = ntohs((unsigned short)row.dwLocalPort);

conn.RemoteAddr = "0.0.0.0";

conn.RemotePort = 0;

conn.State = "LISTEN";

conn.PID = row.dwOwningPid;

conn.ProcessName = GetProcessName(row.dwOwningPid);

conn.Timestamp = (long long)time(0);

connections.push_back(conn);

}

}

free(pTcpTable);

return connections;

}

// ============================================================

// Print Functions

// ============================================================

void SetConsoleColor(int color) {

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);

}

void PrintHeader() {

SetConsoleColor(11); // Cyan

printf("\n");

printf("============================================================================\n");

printf(" GetExtendedTcpTable - Ultra-fast Network Monitor v1.0\n");

printf(" User-mode only, No driver required\n");

printf("============================================================================\n");

printf("\n");

SetConsoleColor(7); // White

}

void PrintTableHeader() {

SetConsoleColor(14); // Yellow

printf("Time | Protocol | Local Address | Remote Address | State | PID | Process\n");

printf("─────────────────────────────────────────────────────────────────────────────────────────────────────\n");

SetConsoleColor(7);

}

void PrintConnection(const NetworkConnection& conn) {

printf("%s | ", GetCurrentTimeString().c_str());

printf("%-8s | ", conn.Protocol.c_str());

char localStr[32], remoteStr[32];

sprintf_s(localStr, sizeof(localStr), "%s:%lu", conn.LocalAddr.c_str(), conn.LocalPort);

sprintf_s(remoteStr, sizeof(remoteStr), "%s:%lu", conn.RemoteAddr.c_str(), conn.RemotePort);

printf("%-20s | ", localStr);

printf("%-20s | ", remoteStr);

printf("%-8s | ", conn.State.c_str());

printf("%-5lu | ", conn.PID);

printf("%s\n", conn.ProcessName.c_str());

}

void PrintStatistics(int connectionCount, double avgTimeMs) {

SetConsoleColor(10); // Green

printf("\n[STATS] Poll#%lld | Connections:%d | AvgTime:%.2fms | Memory:%lldMB | Events:%lld\n",

g_pollCount, connectionCount, avgTimeMs, GetMemoryUsageMB(), g_eventCount);

SetConsoleColor(7);

printf("\n");

}

// ============================================================

// Monitor Function

// ============================================================

void MonitorNetwork(int intervalSeconds = 1) {

PrintHeader();

printf("Starting network monitor, interval: %d seconds\n", intervalSeconds);

printf("Listening for TCP/UDP connection changes...\n");

printf("Press Ctrl+C to stop\n\n");

PrintTableHeader();

long long totalTimeMs = 0;

while (true) {

auto loopStart = high_resolution_clock::now();

g_pollCount++;

// Get all connections

auto tcpConns = GetTcpConnections();

auto udpConns = GetUdpConnections();

auto listenerConns = GetTcpListeners();

// Merge all connections

map<string, NetworkConnection> currentConnections;

for (const auto& conn : tcpConns) {

currentConnections[conn.GetKey()] = conn;

}

for (const auto& conn : udpConns) {

currentConnections[conn.GetKey()] = conn;

}

for (const auto& conn : listenerConns) {

currentConnections[conn.GetKey()] = conn;

}

// Detect new connections

for (const auto& pair : currentConnections) {

if (g_previousConnections.find(pair.first) == g_previousConnections.end()) {

g_eventCount++;

SetConsoleColor(10); // Green

printf("[+] ");

SetConsoleColor(7);

PrintConnection(pair.second);

}

}

// Detect closed connections

for (const auto& pair : g_previousConnections) {

if (currentConnections.find(pair.first) == currentConnections.end()) {

g_eventCount++;

SetConsoleColor(12); // Red

printf("[-] ");

SetConsoleColor(7);

PrintConnection(pair.second);

}

}

// Update cache

g_previousConnections = currentConnections;

auto loopEnd = high_resolution_clock::now();

long long loopTimeMs = duration_cast<milliseconds>(loopEnd - loopStart).count();

totalTimeMs += loopTimeMs;

// Print stats every 5 polls

if (g_pollCount % 5 == 0) {

double avgTimeMs = (double)totalTimeMs / g_pollCount;

PrintStatistics((int)currentConnections.size(), avgTimeMs);

PrintTableHeader();

}

// Sleep until next interval

long long sleepMs = max(0LL, (long long)intervalSeconds * 1000 - loopTimeMs);

if (sleepMs > 0) {

Sleep((DWORD)sleepMs);

}

}

}

// ============================================================

// Performance Test

// ============================================================

void RunPerformanceBenchmark() {

SetConsoleColor(11); // Cyan

printf("\n====================================================================\n");

printf(" GetExtendedTcpTable Performance Test\n");

printf("====================================================================\n\n");

SetConsoleColor(7);

printf("Running performance test with 20 iterations...\n\n");

long long totalTimeMs = 0;

int totalConnections = 0;

int iterations = 20;

for (int i = 0; i < iterations; i++) {

auto start = high_resolution_clock::now();

auto tcpConns = GetTcpConnections();

auto udpConns = GetUdpConnections();

int connCount = (int)(tcpConns.size() + udpConns.size());

totalConnections = connCount;

auto end = high_resolution_clock::now();

long long timeMs = duration_cast<milliseconds>(end - start).count();

totalTimeMs += timeMs;

printf("Iteration #%-2d: %3lldms, Connections: %d\n", i + 1, timeMs, connCount);

}

double avgTimeMs = (double)totalTimeMs / iterations;

SetConsoleColor(10); // Green

printf("\nPerformance Test Results:\n\n");

printf(" Total Connections: %d\n", totalConnections);

printf(" Iterations: %d\n", iterations);

printf(" Total Time: %lld ms\n", totalTimeMs);

printf(" Average Time: %.2f ms\n", avgTimeMs);

printf(" Memory Usage: %lld MB\n\n", GetMemoryUsageMB());

printf("Performance Rating:\n");

if (avgTimeMs < 50) {

printf(" ***** EXCELLENT (< 50ms) *****\n");

}

else if (avgTimeMs < 100) {

printf(" **** VERY GOOD (< 100ms) ****\n");

}

else if (avgTimeMs < 200) {

printf(" *** GOOD (< 200ms) ***\n");

}

else {

printf(" ** FAIR (> 200ms) **\n");

}

printf("\n[OK] Can definitely poll every 1 second!\n\n");

SetConsoleColor(7);

}

// ============================================================

// Show Current Connections

// ============================================================

void ShowCurrentConnections() {

printf("\nFetching all current network connections...\n\n");

auto start = high_resolution_clock::now();

auto tcpConns = GetTcpConnections();

auto udpConns = GetUdpConnections();

auto listenerConns = GetTcpListeners();

auto end = high_resolution_clock::now();

long long timeMs = duration_cast<milliseconds>(end - start).count();

PrintTableHeader();

SetConsoleColor(14);

printf("\n=== TCP Connections (%zu) ===\n", tcpConns.size());

SetConsoleColor(7);

for (const auto& conn : tcpConns) {

PrintConnection(conn);

}

SetConsoleColor(14);

printf("\n=== TCP Listeners (%zu) ===\n", listenerConns.size());

SetConsoleColor(7);

for (const auto& conn : listenerConns) {

PrintConnection(conn);

}

SetConsoleColor(14);

printf("\n=== UDP Bindings (%zu) ===\n", udpConns.size());

SetConsoleColor(7);

for (const auto& conn : udpConns) {

PrintConnection(conn);

}

SetConsoleColor(10);

printf("\nTotal: %zu network connections\n",

tcpConns.size() + udpConns.size() + listenerConns.size());

printf("Time elapsed: %lld ms\n\n", timeMs);

SetConsoleColor(7);

}

// ============================================================

// Main Function

// ============================================================

int main() {

// Initialize API functions

InitializeAPIFunctions();

if (!pGetExtendedTcpTable || !pGetExtendedUdpTable) {

printf("ERROR: Failed to load required API functions\n");

printf("Make sure you are running on Windows XP SP1 or later\n");

return 1;

}

PrintHeader();

printf("Available Operations:\n");

printf(" 1. Performance Test\n");

printf(" 2. Show Current Connections\n");

printf(" 3. Real-time Monitor (1 second interval)\n");

printf(" 4. Real-time Monitor (5 second interval)\n");

printf("\nSelect option (1-4): ");

int choice = 0;

scanf_s("%d", &choice);

switch (choice) {

case 1:

RunPerformanceBenchmark();

printf("Press Enter to exit...");

getchar();

getchar();

break;

case 2:

ShowCurrentConnections();

printf("Press Enter to exit...");

getchar();

getchar();

break;

case 3:

MonitorNetwork(1);

break;

case 4:

MonitorNetwork(5);

break;

default:

printf("Invalid option\n");

}

return 0;

}

相关推荐
刘景贤18 小时前
C/C++开发环境
开发语言·c++
OasisPioneer20 小时前
现代 C++ 全栈教程 - Modern-CPP-Full-Stack-Tutorial
开发语言·c++·开源·github
liulilittle20 小时前
XDP to TC : TUN eBPF NAT
c++
花开莫与流年错_20 小时前
ZeroMQ基本示例使用
c++·消息队列·mq·示例·zeromq
qq_4160187221 小时前
C++中的模板方法模式
开发语言·c++·算法
jyyyx的算法博客1 天前
KMP 算法
c++·kmp
Emberone1 天前
从C到C++:一脚踹开面向对象的大门
开发语言·c++
DDzqss1 天前
3.25打卡day45
c++·算法
JMchen1231 天前
Android NDK开发从入门到实战:解锁应用性能的终极武器
android·开发语言·c++·python·c#·android studio·ndk开发
程序猿编码1 天前
隐匿注入型ELF加壳器:原理、设计与实现深度解析(C/C++ 代码实现)
c语言·网络·c++·elf·代码注入