22

我已经编写了一个程序来将 UDP 数据包从客户端发送到服务器。

这是发射器代码:

import java.io.IOException;
import java.net.*;

public class JavaApplication9 {    
    public static void main(String[] args) throws UnknownHostException, SocketException, IOException  {
        // TODO code application logic here
        byte[] buffer = {10,23,12,31,43,32,24};
        byte [] IP = {-64,-88,1,106};
        InetAddress address = InetAddress.getByAddress(IP);
        DatagramPacket packet = new DatagramPacket(
                buffer, buffer.length, address, 57
                );
        DatagramSocket datagramSocket = new DatagramSocket();
        datagramSocket.send(packet);
        System.out.println(InetAddress.getLocalHost().getHostAddress());
    }
}

接收代码函数是这样的:

public void run() {
    try {
        DatagramSocket serverSocket = new DatagramSocket(port);
        byte[] receiveData = new byte[8];
        byte[] sendData = new byte[8];

        while (true) {
              DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
              serverSocket.receive(receivePacket);
              String sentence = new String( receivePacket.getData());
              System.out.println("RECEIVED: " + sentence);
              InetAddress IPAddress = receivePacket.getAddress();
              String sendString = "polo";
              sendData = sendString.getBytes();
              DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
              serverSocket.send(sendPacket);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

我使用了 Wireshark 程序。UDP 数据包在接收方的 Wireshark 程序中被接收到,但 Java 程序无法识别它,程序只是一直监听端口而没有任何反应?

4

1 回答 1

36

接收方必须设置接收方的端口以匹配发送方 DatagramPacket 中设置的端口。对于调试,请尝试侦听端口 > 1024(例如 5000 或 9000)。< 1024 的端口通常由系统服务使用,需要管理员权限才能绑定到此类端口。

如果接收方将数据包发送到它正在侦听的硬编码端口(例如端口 57)并且发送方在同一台机器上,那么您将创建一个到接收方本身的环回。始终使用数据包中指定的端口,如果是生产软件,则需要检查以防止出现这种情况。

数据包无法到达目的地的另一个原因是发送方指定的 IP 地址错误。UDP 与 TCP 不同,即使地址不可达,UDP 也会尝试发送数据包,并且发送方不会收到错误指示。您可以通过在接收器中打印地址来检查这一点,作为调试的预防措施。

在您设置的发件人中:

 byte [] IP= { (byte)192, (byte)168, 1, 106 };
 InetAddress address = InetAddress.getByAddress(IP);

但使用字符串形式的地址可能更简单:

 InetAddress address = InetAddress.getByName("192.168.1.106");

换句话说,您将目标设置为 192.168.1.106。如果这不是接收者,那么您将不会收到数据包。

这是一个可以工作的简单 UDP 接收器:

import java.io.IOException;
import java.net.*;

public class Receiver {

    public static void main(String[] args) {
        int port = args.length == 0 ? 57 : Integer.parseInt(args[0]);
        new Receiver().run(port);
    }

    public void run(int port) {    
      try {
        DatagramSocket serverSocket = new DatagramSocket(port);
        byte[] receiveData = new byte[8];
        String sendString = "polo";
        byte[] sendData = sendString.getBytes("UTF-8");

        System.out.printf("Listening on udp:%s:%d%n",
                InetAddress.getLocalHost().getHostAddress(), port);     
        DatagramPacket receivePacket = new DatagramPacket(receiveData,
                           receiveData.length);

        while(true)
        {
              serverSocket.receive(receivePacket);
              String sentence = new String( receivePacket.getData(), 0,
                                 receivePacket.getLength() );
              System.out.println("RECEIVED: " + sentence);
              // now send acknowledgement packet back to sender     
              DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length,
                   receivePacket.getAddress(), receivePacket.getPort());
              serverSocket.send(sendPacket);
        }
      } catch (IOException e) {
              System.out.println(e);
      }
      // should close serverSocket in finally block
    }
}
于 2012-12-08T18:41:12.913 回答