本文共 3388 字,大约阅读时间需要 11 分钟。
注意这是发的广播信息,同一网段中其它机器都会收到这个信息(只有特殊的监听这类消息的机器会做出回应):
SendUDP.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.UnknownHostException; public class SendUDP { public static void main(String[] args) throws Exception { // Use this port to send broadcast packet @SuppressWarnings ( "resource" ) final DatagramSocket detectSocket = new DatagramSocket( 8888 ); // Send packet thread new Thread( new Runnable() { @Override public void run() { System.out.println( "Send thread started." ); while ( true ) { try { byte [] buf = new byte [ 1024 ]; int packetPort = 9999 ; // Broadcast address InetAddress hostAddress = InetAddress.getByName( "192.168.184.255" ); BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); String outMessage = stdin.readLine(); if (outMessage.equals( "bye" )) break ; buf = outMessage.getBytes(); System.out.println( "Send " + outMessage + " to " + hostAddress); // Send packet to hostAddress:9999, server that listen // 9999 would reply this packet DatagramPacket out = new DatagramPacket(buf, buf.length, hostAddress, packetPort); detectSocket.send(out); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } }).start(); // Receive packet thread. new Thread( new Runnable() { @Override public void run() { System.out.println( "Receive thread started." ); while ( true ) { byte [] buf = new byte [ 1024 ]; DatagramPacket packet = new DatagramPacket(buf, buf.length); try { detectSocket.receive(packet); } catch (IOException e) { e.printStackTrace(); } String rcvd = "Received from " + packet.getSocketAddress() + ", Data=" + new String(packet.getData(), 0 , packet.getLength()); System.out.println(rcvd); } } }).start(); } } |
ReceiveUDP.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | import java.net.DatagramPacket; import java.net.DatagramSocket; public class ReceiveUDP { public static void main(String[] args) throws Exception { int listenPort = 9999 ; byte [] buf = new byte [ 1024 ]; DatagramPacket packet = new DatagramPacket(buf, buf.length); @SuppressWarnings ( "resource" ) DatagramSocket responseSocket = new DatagramSocket(listenPort); System.out.println( "Server started, Listen port: " + listenPort); while ( true ) { responseSocket.receive(packet); String rcvd = "Received " + new String(packet.getData(), 0 , packet.getLength()) + " from address: " + packet.getSocketAddress(); System.out.println(rcvd); // Send a response packet to sender String backData = "DCBA" ; byte [] data = backData.getBytes(); System.out.println( "Send " + backData + " to " + packet.getSocketAddress()); DatagramPacket backPacket = new DatagramPacket(data, 0 , data.length, packet.getSocketAddress()); responseSocket.send(backPacket); } } } |
下图是SendUDP端的执行截图,发送内容为Message:
在SendUDP端发送了消息后,UDP端会立即显示收到消息,如下图:
正如第一幅图看到的,我在同一子网下的两台机器上运行着ReceiveUDP,于是两台机器都做出了回应。
如果将这种方式移植到Android手机上,可以用来探测同一WiFi下的其它设备(前提是这些设备上运行着类似ReceiveUDP的),以获取它们的IP地址。此后可以建立TCP连接,做其他的事情。有人说可以用Ping网段的方式来发现其它设备,但对于Android来说,这个方式并不可靠。因为判定消息不可达的时间难以确定。
转载地址:http://mxaal.baihongyu.com/