我的代码基于《 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地址。
这可能是个话题,但是如果网络设置有问题,请提供一个好的教程的链接,因为我找不到有效的教程。
答案 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。
但是目前的问题是没有人在听。当然不是您的服务器程序。