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

时间:2018-06-19 11:42:58

标签: c++ winsock2

我的代码基于《 Microsoft Windows Second Edition的网络编程》一书,该书可以PDF的形式在网上找到。

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

public class Expectations {
...
  @IntDef(value = {Gravity.LEFT, Gravity.RIGHT, Gravity.END, Gravity.START, Gravity.TOP, Gravity.BOTTOM})
    @interface GravityIntDef {
    }
...

对于客户端应用程序是:

-keep class com.github.florent37.expectanim.core.** { *; }
-keep enum com.github.florent37.expectanim.core.** { *; }
-keep interface com.github.florent37.expectanim.core.** { *; }

-keepclassmembers class com.github.florent37.expectanim.core.** {
    *;
}
-keepclassmembers enum com.github.florent37.expectanim.core.** {
    *;
}
-keepclassmembers interface com.github.florent37.expectanim.core.** {
    *;
}

-keep public @interface com.github.florent37.expectanim.core.Expectations.GravityIntDef
-keep public @interface com.github.florent37.expectanim.core.Expectations.GravityScaleVerticalIntDef
-keep public @interface com.github.florent37.expectanim.core.Expectations.GravityScaleHorizontalIntDef

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

要澄清:

当我说到“插入IP地址”时,我的意思是写它而不是#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(); }

通过本地IP,我的意思是我的计算机的本地IP地址是在控制台中使用#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,我在"-->insert ip here<--"上进行了检查,并将端口5150转发到了本地IP地址。

这可能是个话题,但是如果网络设置有问题,请提供一个好的教程的链接,因为我找不到有效的教程。

1 个答案:

答案 0 :(得分:0)

好的代码。漂亮又简单。我要做的就是剪切并粘贴(并添加#pragma comment (lib, "ws2_32.lib"))。

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

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

我们在superuser的朋友有这样的话:关于通过[实现NAT的路由器发送UDP数据包(这就是您在那儿拥有的地址)并得到答案

  

如果机器A从与目标端口(“端口N”)相同的源端口发送[UDP]帧,并且如果NAT能够保留该源端口(即配置为在可能的情况下保留源端口,并且该源端口未使用),那么您可以期望对“端口N”的答复将返回到计算机A。

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