注意这是发的广播信息,同一网段中其它机器都会收到这个信息(只有特殊的监听这类消息的机器会做出回应):
SendUDP.java
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
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来说,这个方式并不可靠。因为判定消息不可达的时间难以确定。