使用Win32 API获得端口占用列表并关闭对应进程
程序员文章站
2024-03-01 12:12:16
...
获得端口占用可以用命令netstat -ab
实现,结束进程可以用taskkill
,但是用C++怎么实现呢?
答案是Windows已经提供了API实现功能。GetTcpTable可以得到当前占用的端口数量以及具体的ip和端口,但是得不到对应的进程。GetTcpTable2可以额外获得占用端口对应进程的pid,拿到pid,后面问题就好办了。
下面是效果图:
源码:
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <iostream>
#include <ws2tcpip.h>
#include <Windows.h>
#include <psapi.h>//GetModuleFileNameEx
#include <iphlpapi.h>
#pragma comment(lib, "iphlpapi.lib")
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
DWORD GetIdOfOccupiedPortProcess(unsigned short port)
{
ULONG ulSize=sizeof(MIB_TCPTABLE2);
PMIB_TCPTABLE2 pTcpTable = (PMIB_TCPTABLE2)malloc(ulSize);
if (pTcpTable == nullptr)
throw runtime_error("memory is not enough.");
if (GetTcpTable2(pTcpTable, &ulSize, TRUE) == ERROR_INSUFFICIENT_BUFFER)
{
free(pTcpTable);
pTcpTable = (PMIB_TCPTABLE2)malloc(ulSize);
if (pTcpTable == nullptr)
throw runtime_error("memory is not enough.");
}
if (GetTcpTable2(pTcpTable, &ulSize, TRUE) == NO_ERROR)
{
cout << "start finding TCP port:" << endl;
for (int i = 0; i < pTcpTable->dwNumEntries; ++i)
{
unsigned short localPort = ntohs((u_short)pTcpTable->table[i].dwLocalPort);
cout << localPort << endl;
auto pid = pTcpTable->table[i].dwOwningPid;
if (port == localPort)
{
cout << "found the destination port." << endl;
return pid;
}
}
}
return 0;
}
int main(int argc, char* argv[])
{
while (1)
{
unsigned short port;
cout << "Please input a port number:";
cin >> port;
auto pid = GetIdOfOccupiedPortProcess(port);
if (pid == 0)
{
cout << "No program." << endl;
continue;
}
HANDLE hProcess = ::OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION, FALSE, pid);
if (hProcess == NULL)
{
cout << "Failed in OpenProcess. Maybe no authorization." << endl;
return -1;
}
TCHAR buf[MAX_PATH];
if (GetModuleFileNameEx(hProcess, 0, buf, MAX_PATH))
{
cout << "Do you want to kill the process "<<buf <<"?(y/n)"<< endl;
}
else
{
cout << "Failed in GetModuleFileNameEx. Maybe no authorization." << endl;
return -1;
}
char key;
cin >> key;
if (key == 'y')
{
if (::TerminateProcess(hProcess, 0))
cout << "Success." << endl;
}
CloseHandle(hProcess);
}
return 0;
}
参考
GetTcpTable2 function
Build your own netstat.exe with c# | Tim Van Wassenhove’s blog
h
如何在C++中获取进程名?