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