Java发送和接收广播的UDP,用于探测局域网中指定类型的设备

注意这是发的广播信息,同一网段中其它机器都会收到这个信息(只有特殊的监听这类消息的机器会做出回应):

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:

Java发送和接收广播的UDP,用于探测局域网中指定类型的设备

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

Java发送和接收广播的UDP,用于探测局域网中指定类型的设备

正如第一幅图看到的,我在同一子网下的两台机器上运行着ReceiveUDP,于是两台机器都做出了回应。


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

上一篇:虚拟*处理器新星软机公司即将被收购


下一篇:自动化运维工具ansible安装及使用