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