1.c语言代码
2.编译命令
============另外的程序================================================
检测端口程序的编译命令:
ports.c
gcc port_tool.c -o port_tool.exe -lws2_32 -lpsapi -static
-
port_tool.c 代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <windows.h>#include <tlhelp32.h>
#include <ws2tcpip.h>
#include <shellapi.h>#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "shell32.lib")// 颜色定义
#define COLOR_RESET 7
#define COLOR_GREEN 10
#define COLOR_YELLOW 14
#define COLOR_CYAN 11
#define COLOR_RED 12
#define COLOR_GRAY 8void SetColor(int color) {
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, color);
}// 检查是否管理员
BOOL IsRunningAsAdmin() {
BOOL isAdmin = FALSE;
PSID adminGroup = NULL;
SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;if (AllocateAndInitializeSid(&ntAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &adminGroup)) { CheckTokenMembership(NULL, adminGroup, &isAdmin); FreeSid(adminGroup); } return isAdmin;}
// 自动提权
void ElevateSelf() {
char exePath[MAX_PATH];
GetModuleFileName(NULL, exePath, MAX_PATH);
ShellExecute(NULL, "runas", exePath, NULL, NULL, SW_SHOWNORMAL);
exit(0);
}// 执行CMD命令并获取输出
char* ExecuteCommand(const char* cmd) {
char buffer[4096] = {0};
char* result = (char*)malloc(8192);
if (!result) return NULL;
result[0] = '\0';FILE* pipe = _popen(cmd, "r"); if (!pipe) { free(result); return NULL; } while (fgets(buffer, sizeof(buffer), pipe) != NULL) { strcat(result, buffer); } _pclose(pipe); return result;}
// 通过PID获取进程名
char* GetProcessNameByPID(DWORD pid) {
static char processName[256] = "未知进程";
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) {
return processName;
}PROCESSENTRY32 pe; pe.dwSize = sizeof(PROCESSENTRY32); if (Process32First(hSnapshot, &pe)) { do { if (pe.th32ProcessID == pid) { strcpy(processName, pe.szExeFile); char* dot = strstr(processName, ".exe"); if (dot) *dot = '\0'; CloseHandle(hSnapshot); return processName; } } while (Process32Next(hSnapshot, &pe)); } CloseHandle(hSnapshot); return processName;}
// 端口信息结构体
typedef struct {
BOOL isTCP;
BOOL isUDP;
DWORD pid;
char processName[256];
} PortInfo;// 检测端口
PortInfo DetectPort(int port) {
PortInfo info = {FALSE, FALSE, 0, "未知进程"};
char cmd[256];
char* output = NULL;sprintf(cmd, "netstat -ano | findstr \":%d \"", port); output = ExecuteCommand(cmd); if (output && strlen(output) > 0) { char* line = strtok(output, "\n"); while (line) { if (strstr(line, "UDP")) { info.isUDP = TRUE; char* lastSpace = strrchr(line, ' '); if (lastSpace) { while (*lastSpace == ' ') lastSpace++; info.pid = atoi(lastSpace); } } else if (strstr(line, "LISTENING") || strstr(line, "ESTABLISHED")) { info.isTCP = TRUE; char* lastSpace = strrchr(line, ' '); if (lastSpace) { while (*lastSpace == ' ') lastSpace++; info.pid = atoi(lastSpace); } } if (info.pid > 0) { char* name = GetProcessNameByPID(info.pid); strcpy(info.processName, name); } line = strtok(NULL, "\n"); } } free(output); // 主动探测 if (!info.isTCP && !info.isUDP) { WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) == 0) { SOCKET sock; struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // TCP测试 sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock != INVALID_SOCKET) { u_long mode = 1; ioctlsocket(sock, FIONBIO, &mode); connect(sock, (struct sockaddr*)&addr, sizeof(addr)); fd_set fdSet; FD_ZERO(&fdSet); FD_SET(sock, &fdSet); struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 500000; if (select(0, NULL, &fdSet, NULL, &timeout) > 0) { info.isTCP = TRUE; } closesocket(sock); } // UDP测试 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock != INVALID_SOCKET) { struct sockaddr_in localAddr; localAddr.sin_family = AF_INET; localAddr.sin_port = htons(port); localAddr.sin_addr.s_addr = INADDR_ANY; if (bind(sock, (struct sockaddr*)&localAddr, sizeof(localAddr)) != 0) { info.isUDP = TRUE; char cmd2[256]; sprintf(cmd2, "netstat -ano | findstr \"UDP\" | findstr \":%d \"", port); char* out2 = ExecuteCommand(cmd2); if (out2 && strlen(out2) > 0) { char* lastSpace = strrchr(out2, ' '); if (lastSpace) { while (*lastSpace == ' ') lastSpace++; info.pid = atoi(lastSpace); if (info.pid > 0) { char* name = GetProcessNameByPID(info.pid); strcpy(info.processName, name); } } } free(out2); } closesocket(sock); } WSACleanup(); } } return info;}
// 结束进程
BOOL KillProcess(DWORD pid) {
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
if (hProcess == NULL) {
return FALSE;
}
BOOL result = TerminateProcess(hProcess, 0);
CloseHandle(hProcess);
return result;
}// 主程序
int main() {
// 自动提权
if (!IsRunningAsAdmin()) {
MessageBox(NULL,
"端口检测工具需要管理员权限才能正常工作!\n点击确定后自动请求提权...",
"权限提示", MB_OK | MB_ICONINFORMATION);
ElevateSelf();
return 0;
}SetColor(COLOR_CYAN); printf("========================================\n"); printf(" 端口检测工具 v2.0 (C语言版)\n"); printf("========================================\n\n"); SetColor(COLOR_RESET); WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); while (1) { SetColor(COLOR_CYAN); printf("请输入端口号 (输入 0 退出): "); SetColor(COLOR_RESET); char input[32]; fgets(input, sizeof(input), stdin); input[strcspn(input, "\n")] = 0; int port = atoi(input); if (port == 0) { break; } if (port < 1 || port > 65535) { SetColor(COLOR_RED); printf("❌ 无效端口号,请输入 1-65535 之间的数字\n\n"); SetColor(COLOR_RESET); continue; } printf("\n🔍 正在检测端口 %d...\n\n", port); PortInfo info = DetectPort(port); SetColor(COLOR_GREEN); printf("========== 检测结果 ==========\n"); if (info.isTCP && info.isUDP) { SetColor(COLOR_GREEN); printf("✅ 端口 %d: TCP + UDP 都在使用\n", port); } else if (info.isTCP) { SetColor(COLOR_GREEN); printf("✅ 端口 %d: TCP 协议\n", port); } else if (info.isUDP) { SetColor(COLOR_GREEN); printf("✅ 端口 %d: UDP 协议\n", port); } else { SetColor(COLOR_GRAY); printf("❌ 端口 %d: 未检测到任何服务\n", port); SetColor(COLOR_RESET); printf("================================\n\n按任意键继续..."); getchar(); printf("\n"); continue; } if (info.pid > 0) { SetColor(COLOR_YELLOW); printf("📌 占用进程: %s (PID: %d)\n", info.processName, info.pid); SetColor(COLOR_RESET); printf("\n是否结束该进程以释放端口? (y/n): "); char choice[8]; fgets(choice, sizeof(choice), stdin); if (choice[0] == 'y' || choice[0] == 'Y') { if (KillProcess(info.pid)) { SetColor(COLOR_GREEN); printf("✅ 已结束进程 %s (PID: %d),端口已释放\n", info.processName, info.pid); SetColor(COLOR_RESET); } else { SetColor(COLOR_RED); printf("❌ 结束进程失败!请检查是否有足够权限\n"); SetColor(COLOR_RESET); } } } else { SetColor(COLOR_GRAY); printf("📌 端口未被占用,无需关闭\n"); SetColor(COLOR_RESET); } SetColor(COLOR_GREEN); printf("================================\n"); SetColor(COLOR_RESET); printf("\n按任意键继续..."); getchar(); printf("\n\n"); } WSACleanup(); SetColor(COLOR_CYAN); printf("感谢使用!\n"); SetColor(COLOR_RESET); return 0;}