檢查某個端口是否被udp網絡程序佔用

代碼分爲2部分;

1.隨機生成一個未被 udp 佔用的端口號

2.啓動一個 udp程序,使用我們剛纔找到的端口號

 

#include <iostream>  
#include <sys/socket.h>  
#include <netinet/in.h>  
#include <cstring>  
#include <cstdlib>  
#include <ctime>  
#include <unistd.h>  
#include <errno.h>  
  

const int MAXLINE = 1024;  
  
int find_available_udp_port() {  
    const int MIN_PORT = 1024; // 通常1024以下的端口是保留的  
    const int MAX_PORT = 65535; // UDP端口的最大範圍  
    int sockfd, port = -1;  
    struct sockaddr_in serv_addr;  
  
    srand(time(nullptr)); // 初始化隨機數生成器  
    int iMaxTryCount = 100;
    int iStartTryCount = 0;
  
    // 不斷嘗試直到找到可用的端口  
    do {
        port = MIN_PORT + rand() % (MAX_PORT - MIN_PORT + 1); // 生成隨機端口號  
          // 創建UDP socket  
        if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {  
            std::cerr << "ERROR opening socket" << std::endl;  
            return -1; // 錯誤處理  
        }  
        // 設置服務器的地址和端口  
        memset(&serv_addr, 0, sizeof(serv_addr));  
        serv_addr.sin_family = AF_INET;  
        serv_addr.sin_addr.s_addr = INADDR_ANY; // 監聽所有網絡接口  
        serv_addr.sin_port = htons(port); // 端口號  
  
        // 嘗試綁定到端口  
        if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {  
            // 如果綁定失敗,關閉socket並繼續嘗試  
            close(sockfd);  
            if (errno != EADDRINUSE) {  
                std::cerr << "ERROR on binding: " << strerror(errno) << std::endl;  
                return -1; // 非EADDRINUSE錯誤,返回錯誤  
            }else{
                printf("Address already in use, port:%d\r\n", port);
                //端口被佔用,繼續嘗試其他方法... continue
            }
        } else {  
            // 綁定成功,端口可用,關閉socket並返回端口號  
            close(sockfd);  
            return port;  
        }  
        ++iStartTryCount;
    } while (iStartTryCount<iMaxTryCount); // 理論上,只要端口範圍足夠大,總會找到一個可用的端口  
    return port;
}  
  
int main() {  
    int port = find_available_udp_port();  
    if (port >= 0) {  
        std::cout << "Found available UDP port: " << port << std::endl;  
    } else {  
        std::cerr << "Failed to find an available UDP port." << std::endl;  
    }  


    int sockfd;  
    struct sockaddr_in servaddr, cliaddr;  
    char buffer[MAXLINE];  
    socklen_t len;  
  
    // 創建UDP socket  
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {  
        std::cerr << "ERROR opening socket" << std::endl;  
        return 1;  
    }  
  
    // 清除servaddr結構並設置地址家族  
    memset(&servaddr, 0, sizeof(servaddr));  
    servaddr.sin_family = AF_INET;  
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY); // 監聽所有網絡接口  
    servaddr.sin_port = htons(port); // 端口號  
  
    // 綁定到指定的端口  
    if (bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {  
        std::cerr << "ERROR on binding" << std::endl;  
        return 1;  
    }  
  
    // 打印啓動成功信息  
    std::cout << "Server started and listening on port " << port << std::endl;  
  
    // 無限循環,等待接收數據  
    while (true) {  
        len = sizeof(cliaddr);  
        ssize_t n = recvfrom(sockfd, (char *)buffer, MAXLINE, MSG_WAITALL,  
                             (struct sockaddr *) &cliaddr, &len);  
        buffer[n] = '\0';  
  
        if (n < 0) {  
            std::cerr << "ERROR in recvfrom" << std::endl;  
            break;  
        }  
  
        // 打印接收到的數據  
        std::cout << "Received from client: " << buffer << std::endl;  
  
        // (可選)發送數據回客戶端  
        //sendto(sockfd, (const char *)buffer, strlen(buffer), MSG_CONFIRM,  
        //       (const struct sockaddr *) &cliaddr, sizeof(cliaddr));  
    }  
  
    // 關閉socket  
    close(sockfd);  
    return 0;  
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章