注意这是发的广播信息,同一网段中其它机器都会收到这个信息(只有特殊的监听这类消息的机器会做出回应):
SendUDP.java
1import java.io.BufferedReader; 2import java.io.IOException; 3import java.io.InputStreamReader; 4import java.net.DatagramPacket; 5import java.net.DatagramSocket; 6import java.net.InetAddress; 7import java.net.UnknownHostException; 8 9public class SendUDP { 10 public static void main(String[] args) throws Exception { 11 // Use this port to send broadcast packet 12 @SuppressWarnings("resource") 13 final DatagramSocket detectSocket = new DatagramSocket(8888); 14 15 // Send packet thread 16 new Thread(new Runnable() { 17 @Override 18 public void run() { 19 System.out.println("Send thread started."); 20 while (true) { 21 try { 22 byte[] buf = new byte[1024]; 23 int packetPort = 9999; 24 25 // Broadcast address 26 InetAddress hostAddress = InetAddress.getByName("192.168.184.255"); 27 BufferedReader stdin = new BufferedReader( 28 new InputStreamReader(System.in)); 29 String outMessage = stdin.readLine(); 30 31 if (outMessage.equals("bye")) 32 break; 33 buf = outMessage.getBytes(); 34 System.out.println("Send " + outMessage + " to " + hostAddress); 35 // Send packet to hostAddress:9999, server that listen 36 // 9999 would reply this packet 37 DatagramPacket out = new DatagramPacket(buf, 38 buf.length, hostAddress, packetPort); 39 detectSocket.send(out); 40 } catch (UnknownHostException e) { 41 e.printStackTrace(); 42 } catch (IOException e) { 43 e.printStackTrace(); 44 } 45 } 46 } 47 }).start(); 48 49 // Receive packet thread. 50 new Thread(new Runnable() { 51 @Override 52 public void run() { 53 System.out.println("Receive thread started."); 54 while(true) { 55 byte[] buf = new byte[1024]; 56 DatagramPacket packet = new DatagramPacket(buf, buf.length); 57 try { 58 detectSocket.receive(packet); 59 } catch (IOException e) { 60 e.printStackTrace(); 61 } 62 String rcvd = "Received from " + packet.getSocketAddress() + ", Data=" 63 + new String(packet.getData(), 0, packet.getLength()); 64 System.out.println(rcvd); 65 } 66 } 67 }).start(); 68 } 69}
ReceiveUDP.java
1import java.net.DatagramPacket; 2import java.net.DatagramSocket; 3 4public class ReceiveUDP { 5 public static void main(String[] args) throws Exception { 6 int listenPort = 9999; 7 byte[] buf = new byte[1024]; 8 DatagramPacket packet = new DatagramPacket(buf, buf.length); 9 @SuppressWarnings("resource") 10 DatagramSocket responseSocket = new DatagramSocket(listenPort); 11 System.out.println("Server started, Listen port: " + listenPort); 12 while (true) { 13 responseSocket.receive(packet); 14 String rcvd = "Received " 15 + new String(packet.getData(), 0, packet.getLength()) 16 + " from address: " + packet.getSocketAddress(); 17 System.out.println(rcvd); 18 19 // Send a response packet to sender 20 String backData = "DCBA"; 21 byte[] data = backData.getBytes(); 22 System.out.println("Send " + backData + " to " + packet.getSocketAddress()); 23 DatagramPacket backPacket = new DatagramPacket(data, 0, 24 data.length, packet.getSocketAddress()); 25 responseSocket.send(backPacket); 26 } 27 } 28}
下图是SendUDP端的执行截图,发送内容为Message:

在SendUDP端发送了消息后,UDP端会立即显示收到消息,如下图:

正如第一幅图看到的,我在同一子网下的两台机器上运行着ReceiveUDP,于是两台机器都做出了回应。
如果将这种方式移植到Android手机上,可以用来探测同一WiFi下的其它设备(前提是这些设备上运行着类似ReceiveUDP的),以获取它们的IP地址。此后可以建立TCP连接,做其他的事情。有人说可以用Ping网段的方式来发现其它设备,但对于Android来说,这个方式并不可靠。因为判定消息不可达的时间难以确定。