即使使用端口转发也无法将 UDP 数据报发送到服务器

问题描述 投票:0回答:1

编辑:我解决了这个问题,事实证明,即使我允许文件接受Mac上防火墙中的传入连接,它仍然阻止它们,在完全禁用它之后,它们现在会通过,所以这是我的机器拒绝数据包并且不是端口转发或代码。

我有一个 C++ 客户端和服务器应用程序,其中服务器被设计为使用 UDP 套接字在端口 44888 上“侦听”传入数据包并输出收到的任何消息。客户端设计为打开 UDP 套接字并通过同一端口向服务器发送数据。

我的路由器有端口转发功能,可以将发送到我的公共 IP 地址和端口 44888 的数据包重定向到我的机器 LAN IP。当我在我的计算机上运行服务器并在同一台计算机上启动客户端时,如果通过我的公共 IP 地址发送数据包将无法通过,但如果我使用 localhost 作为地址,则数据包将无法通过。另外,外网的人也无法使用客户端发送数据包

我尝试在我的机器上使用 netcat 监听端口 44888 上的连接,外部网络中的人可以通过该端口上的 netcat 发送消息,所以我很确定我的端口转发正确,所以我真的不确定什么是问题是。有什么想法吗?

代码非常简陋,如下:

服务器

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

int main() {
    int sockfd;
    struct sockaddr_in serverAddr, clientAddr;
    socklen_t clientAddrLen = sizeof(clientAddr);
    char buffer[1024];

    // Create a UDP socket
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        std::cerr << "Error opening socket" << std::endl;
        return 1;
    }

    // Set up the server address structure
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(44888);
    serverAddr.sin_addr.s_addr = INADDR_ANY;

    // Bind the socket to the server address
    if (bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
        std::cerr << "Error binding socket" << std::endl;
        close(sockfd);
        return 1;
    }

    std::cout << "UDP server listening on port 44888..." << std::endl;

    while (true) {
        // Receive data from clients
        ssize_t bytesRead = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)&clientAddr, &clientAddrLen);
        if (bytesRead < 0) {
            std::cerr << "Error receiving data" << std::endl;
            continue;
        }

        // Print the received message
        buffer[bytesRead] = '\0';
        std::cout << "Received message from " << inet_ntoa(clientAddr.sin_addr) << ":" << ntohs(clientAddr.sin_port) << ": " << buffer << std::endl;
    }

    // Close the socket (unreachable in this example)
    close(sockfd);

    return 0;
}

客户

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

int main() {
    int sockfd;
    struct sockaddr_in serverAddr;

    // Create a UDP socket
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        std::cerr << "Error opening socket" << std::endl;
        return 1;
    }

    // Set up the server address structure
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(44888);
    serverAddr.sin_addr.s_addr = inet_addr("OMITTED"); // Server's IP address

    while (true) {
        // Input a message to send
        std::cout << "Enter a message to send (or type 'exit' to quit): ";
        std::string message;
        std::getline(std::cin, message);

        if (message == "exit") {
            break; // Exit the loop
        }

        // Send the message to the server
        ssize_t bytesSent = sendto(sockfd, message.c_str(), message.size(), 0, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
        if (bytesSent < 0) {
            std::cerr << "Error sending data" << std::endl;
        } else {
            std::cout << "Message sent successfully" << std::endl;
        }
    }

    // Close the socket
    close(sockfd);

    return 0;
}

此图显示我应该在wireshark上接收数据包(红色省略了公共IP地址)

此图显示了外部网络上的一台机器,使用我制作的客户端向我的服务器发送 udp 数据包

此图片显示了我的端口转发

c++ sockets unix udp portforwarding
1个回答
0
投票

我解决了这个问题,事实证明,即使我允许文件接受 Mac 上防火墙中的传入连接,它仍然阻止它们,在完全禁用它之后,它们现在会通过,所以是我的机器拒绝数据包,而不是端口转发或代码。

© www.soinside.com 2019 - 2024. All rights reserved.