使用全局 IP 地址时,C++ winsock 2 应用程序中的代码是否必须更改?

Does the code in a C++ winsock 2 application have to change when using a global IP address?

本文关键字:是否 代码 应用程序 IP 全局 地址 winsock C++      更新时间:2023-10-16

我的代码基于"Microsoft Windows 第二版的网络编程"一书,该书可以PDF格式在线找到。

我的服务器应用程序代码是:

#include <iostream>
#include <winsock2.h>
int main(void)
{
WSADATA wsaData;
SOCKET ReceivingSocket;
SOCKADDR_IN ReceiverAddr;
int Port = 5150;
char buffer;
SOCKADDR_IN SenderAddr;
int SenderAddrSize = sizeof(SenderAddr);
WSAStartup(MAKEWORD(2,2), &wsaData);
ReceivingSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
ReceiverAddr.sin_family = AF_INET;
ReceiverAddr.sin_port = htons(Port);
ReceiverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(ReceivingSocket, (SOCKADDR *)&ReceiverAddr, sizeof(ReceiverAddr));
recvfrom(ReceivingSocket, &buffer, 1, 0, (SOCKADDR *)&SenderAddr, &SenderAddrSize);
std::cout << buffer << std::endl;
buffer = 'b';
sendto(ReceivingSocket, &buffer, 1, 0, (SOCKADDR*)&SenderAddr, SenderAddrSize);
std::cin.get();
closesocket(ReceivingSocket);
WSACleanup();
}

对于客户端应用程序是:

#include <winsock2.h>
#include <iostream>
int main()
{
WSADATA wsaData;
SOCKET SendingSocket;
SOCKADDR_IN ReceiverAddr;
SOCKADDR_IN ex;
int Port = 5150;
char buffer = 'a';
WSAStartup(MAKEWORD(2,2), &wsaData);
SendingSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
ReceiverAddr.sin_family = AF_INET;
ReceiverAddr.sin_port = htons(Port);
ReceiverAddr.sin_addr.s_addr = inet_addr("-->insert ip here<--");
sendto(SendingSocket, &buffer, 1, 0, (SOCKADDR *)&ReceiverAddr, sizeof(ReceiverAddr));
int len = sizeof (ex);
recvfrom(SendingSocket, &buffer, 1, 0, (SOCKADDR*)&ex, &len);
std::cout << buffer << std::endl;
std::cin.get();
closesocket(SendingSocket);
WSACleanup();
}

当我插入本地 IP 时,代码工作得很好 - 应用程序相互检测并交换缓冲区。 但是当我插入我的全局 IP 时,应用程序不会相互检测。是代码有问题,还是使用全局 IP 时必须更改的内容,或者我的网络设置有问题?

澄清一下:

当我说"插入IP地址"时,我的意思是写它而不是"-->insert ip here<--"

通过本地 IP,我指的是我计算机的本地 IP 地址,使用ipconfig命令在控制台中检查。

通过全局IP,我指的是我的路由器的全局IP,我在myglobalip.com上检查了它,并将端口5150转发到我的本地IP地址。

这可能有点偏离主题,但如果网络设置有问题,如果您能提供一个好教程的链接,我将不胜感激,因为我找不到有效的教程。

不错的代码。 很好,很简单。 我所要做的就是剪切和粘贴(并添加#pragma comment (lib, "ws2_32.lib")(。

客户端和服务器是否都在您的 LAN 上运行? 如果是这样,我的测试表明它们将无法通过路由器的外部IP地址相互通信。 这是因为路由器不会环回通过其ADSL/VDSL端口发送的数据包(为什么会这样?(,因此它们只是消失在以太网中。 我尝试在我的路由器上启用 DMZ 和端口转发(至少,您需要一个或另一个(,但没有骰子,这是我所期望的。

因此,要对此进行测试,您将需要拥有自己路由器的朋友的帮助。 假设他正在运行客户端。 然后,您需要将服务器计算机放入路由器的 DMZ 中,或者(更好,因为它更安全(为路由器上的 UDP 端口 5150 设置到服务器计算机的端口转发。 无论哪种情况,都要在局域网上为该计算机提供一个静态 IP 地址,否则它可能会移动。 然后你就有机会看到这项工作。

我们在超级用户的朋友对通过[路由器实现] NAT(这就是您将拥有的(发送UDP数据包并得到答案有这样的说法:

如果计算机 A 从与目标端口相同的源端口("端口 N

"(发送 [UDP] 帧,并且如果 NAT 能够保留该源端口(即,它配置为尽可能保留源端口,并且该源端口未在使用中(,那么您可以期望对"端口 N"的回复返回到计算机 A。

但目前的问题是,没有人在听。 当然不是您的服务器程序。