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