判断是tcp,udp以及关闭windows下的端口

1.c语言代码

2.编译命令

复制代码
============另外的程序================================================
检测端口程序的编译命令:
ports.c
gcc port_tool.c -o port_tool.exe -lws2_32 -lpsapi -static
  1. 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 8

    void 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;

    }