Java DatagramSocket(UDP套接字)仅在先前已发送数据包时才会收到

时间:2013-01-23 02:21:01

标签: java sockets network-programming udp voip

我有以下问题:

我有一个非常简单的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())); 
    } 
} 

有谁知道可能导致此问题的原因?虽然解决方法确实解决了问题,但它对我来说没有任何意义,为什么它最初不起作用,因此解决方案可能实际上并不适用于所有计算机。

此外,应该注意的是,当客户端和服务器都在同一台机器上时,代码工作正常。

2 个答案:

答案 0 :(得分:1)

检查您的PC是否使用私有IP地址,通常以“10.x.x.x”或“192.168.x.x”开头。如果是这样,最可能的原因是您使用的是基于NAT的防火墙,该防火墙共享一个公共地址和多个私有地址。

当您发送数据包出站时,防火墙知道哪个内部地址应该接收返回数据包。但是,当从外部地址启动连接时,它无法知道哪个内部地址应该接收流量。大多数SOHO(小型办公室/家庭办公室)路由器将允许您将流量“端口转发”到特定的内部IP地址。如果您正在使用DHCP,则需要为自己分配一个静态IP地址,否则您的端口转发可能会在将来某个日期停止工作,因为它会抓取不同的IP地址。

答案 1 :(得分:0)

这发生在AWS EC2上。客户端上的端口未在防火墙(安全组)上打开。当您的客户端将数据包发送到服务器时,防火墙会在短时间内从服务器获取数据。如果打开防火墙上的客户端端口,客户端可以从服务器接收而不向服务器发送任何内容。