我有以下问题:
我有一个非常简单的Java数据报客户端和服务器位于远程计算机上。并且客户端不会从服务器接收任何内容,除非它之前向服务器发送了一个数据包(数据包保存的信息并不重要)
以下是我的客户的意见:
public static void TheClient() throws Exception {
ds = new DatagramSocket(clientPort);
while(true) {
DatagramPacket p = new DatagramPacket(buffer, buffer.length);
ds.receive(p);
System.out.println(new String(p.getData(), 0, p.getLength()));
}
}
基本上它所做的只是侦听端口clientPort,然后打印它收到的任何内容。但它不起作用。
现在稍微修改它可以解决问题:
public static void TheClient() throws Exception {
ds = new DatagramSocket(clientPort);
//Sending an empty packet
byte tempBuffer1[] = new byte[10];
InetAddress address = InetAddress.getByName(SERVER_IP);
DatagramPacket packet1 = new DatagramPacket(
tempBuffer1, tempBuffer1.length, address, serverPort);
ds.send(packet1);
while(true) {
DatagramPacket p = new DatagramPacket(buffer,
buffer.length);
ds.receive(p);
System.out.println(new String(p.getData(), 0,
p.getLength()));
}
}
有谁知道可能导致此问题的原因?虽然解决方法确实解决了问题,但它对我来说没有任何意义,为什么它最初不起作用,因此解决方案可能实际上并不适用于所有计算机。
此外,应该注意的是,当客户端和服务器都在同一台机器上时,代码工作正常。
答案 0 :(得分:1)
检查您的PC是否使用私有IP地址,通常以“10.x.x.x”或“192.168.x.x”开头。如果是这样,最可能的原因是您使用的是基于NAT的防火墙,该防火墙共享一个公共地址和多个私有地址。
当您发送数据包出站时,防火墙知道哪个内部地址应该接收返回数据包。但是,当从外部地址启动连接时,它无法知道哪个内部地址应该接收流量。大多数SOHO(小型办公室/家庭办公室)路由器将允许您将流量“端口转发”到特定的内部IP地址。如果您正在使用DHCP,则需要为自己分配一个静态IP地址,否则您的端口转发可能会在将来某个日期停止工作,因为它会抓取不同的IP地址。
答案 1 :(得分:0)
这发生在AWS EC2
上。客户端上的端口未在防火墙(安全组)上打开。当您的客户端将数据包发送到服务器时,防火墙会在短时间内从服务器获取数据。如果打开防火墙上的客户端端口,客户端可以从服务器接收而不向服务器发送任何内容。