检查某个端口是否被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;  
}

 

posted @ 2024-05-14 17:31  He_LiangLiang  阅读(23)  评论(0编辑  收藏  举报