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:

125104_bllV_1434710.png

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

125123_IWYr_1434710.png

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


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

目录
相关文章
|
2天前
|
网络协议 Java
Java的Socket编程:TCP/IP与UDP深入探索
Java的Socket编程:TCP/IP与UDP深入探索
9 0
|
14天前
|
存储 安全 Java
Java一分钟之-泛型擦除与类型安全
【5月更文挑战第20天】Java泛型采用类型擦除机制,在编译期间移除泛型信息,但在编译阶段提供类型安全检查。尽管需要类型转换且可能产生警告,但可以通过特定语法避免。使用泛型时应注意自动装箱拆箱影响性能,无界通配符仅允许读取。理解这些特性有助于编写更安全的代码。
42 4
|
18天前
|
Java 索引
【JAVA基础篇教学】第七篇:Java异常类型说明
【JAVA基础篇教学】第七篇:Java异常类型说明
|
18天前
|
网络协议 算法 Java
【Java网络编程】网络编程概述、UDP通信(DatagramPacket 与 DatagramSocket)
【Java网络编程】网络编程概述、UDP通信(DatagramPacket 与 DatagramSocket)
28 3
|
7天前
|
Java
Java初识泛型 | 如何通过泛型类/泛型方法获取任意类型的三个数的最大值?
本文介绍了如何使用Java中的泛型来实现一个可以比较任意数值类型最大值的功能。。
21 2
|
10天前
|
存储 Java 编译器
Java泛型类型擦除以及类型擦除带来的问题
Java中的泛型是伪泛型,编译时泛型信息会被擦除,例如ListString和ListInteger在JVM中都变为List。泛型擦除后,类型检查主要在编译时完成,针对的是引用而非实际对象。例如,ArrayListString的原始类型是ArrayList,但编译时会对引用调用的方法进行类型检查。类型转换由编译器自动处理,如PairDate的value在访问时会自动转换为`Date`。泛型不能用于基本类型,如ArrayListdouble应写作ArrayListDouble。静态方法和静态类不能使用泛型类的类型参数,但可以定义泛型静态方法。
142 0
|
15天前
|
安全 Java API
Java一分钟之-泛型通配符:上限与下限野蛮类型
【5月更文挑战第19天】Java中的泛型通配符用于增强方法参数和变量的灵活性。通配符上限`? extends T`允许读取`T`或其子类型的列表,而通配符下限`? super T`允许向`T`或其父类型的列表写入。野蛮类型不指定泛型,可能引发运行时异常。注意,不能创建泛型通配符实例,也无法同时指定上下限。理解和适度使用这些概念能提升代码的通用性和安全性,但也需兼顾可读性。
36 3
|
17天前
|
Java Kotlin
关于Java:public函数公开其public / * package * /’参数类型
关于Java:public函数公开其public / * package * /’参数类型
17 3
|
18天前
|
消息中间件 Java RocketMQ
MQ产品使用合集之在同一个 Java 进程内建立三个消费对象并设置三个消费者组订阅同一主题和标签的情况下,是否会发生其中一个消费者组无法接收到消息的现象
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
18天前
|
Java 编译器 C语言
【Java开发指南 | 第五篇】Java变量类型、参数变量及局部变量
【Java开发指南 | 第五篇】Java变量类型、参数变量及局部变量
21 3