Java广播 —如何利用广播做服务发现

通过广播可以在局域网内广播信息,广播接收端通过监听广播信息,可以自动发现局域网内所有的设备/服务信息。

1. 发送广播

在 Java 中通过将 DatagramSocket 设置 setBroadcast(true) 来发送广播。

java 复制代码
DatagramSocket socket = new DatagramSocket();
socket.setBroadcast(true);
java 复制代码
// 广播内容
byte[] broadcastContent = "广播内容".getBytes();
// 发送广播的指定端口
int broadcastPort = 12135;
// 发送广播的地址
InetAddress broadcastAddress = InetAddress.getByName("255.255.255.255");
// 构建广播数据包
DatagramPacket packet = new DatagramPacket(broadcastContent, broadcastContent.length,  broadcastAddress, broadcastPort);
socket.send(pocket);
  • broadcastAddress(255.255.255.255): 表示发送到本地网络中的所有设备,并且不会被路由器转发到其他网络,意味着该网络数据包会广播到局域网中的所有设备。
  • broadcastPort(12135): 表示发送到该端口,广播数据包只能发送到一个端口,不能发送到多个端口。

除了通过 255.255.255.255 也可以设置发送到指定的子网的所有主机。如: 192.168.1.255。

可以通过以下方式获取当前主机所在子网的所有广播地址列表。

java 复制代码
private static List<InetAddress> listAllBroadcastAddresses() throws SocketException {  
    List<InetAddress> broadcastList = new ArrayList<>();
    // 获取所有的网络接口  
    Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();  
    while (interfaces.hasMoreElements()) {  
        NetworkInterface networkInterface = interfaces.nextElement();  
		// 剔除本地回环地址(127.0.0.1) 以及未启用的接口
        if (networkInterface.isLoopback() || !networkInterface.isUp()) {  
            continue;  
        }  
		// 提取每个地址的广播地址
        networkInterface.getInterfaceAddresses().stream()  
                .map(InterfaceAddress::getBroadcast)  
                .filter(Objects::nonNull)  
                .forEach(broadcastList::add);  
    }  
    return broadcastList;  
}

这样就可以从列表中选择向哪一个子网发送广播信息,或是遍历列表都发送。

2. 接收广播

接收广播同样是通过 DatagramSocket 类,但不需要设置为广播模式,需要监听本地端口,这个端口也就是广播发送端广播的端口。

java 复制代码
// 监听端口
DatagramSocket socket = new DatagramSocket(12135);

byte[] receiveBuff = new byte[1024];

DatagramPacket packet = new DatagramPacket(receiveBuff, receiveBuff.length);

// 阻塞式等待接收广播信息
socket.receive(packet);

// 解析广播信息
String receiveContent = new String(packet.getData(), 0, packet.getLength());

System.out.println("接收到广播信息 :" + receiveContent);

3. 应用

通过广播的方式,我们可以做到局域网内的自动服务发现。比如以下技术都是通过广播来做到的

  1. DHCP, 客户端通过广播 255.255.255.255,67端口发现DHCP服务器。
  2. 打印机,物联网设备的设备发现
  3. 局域网游戏服务器的服务发现

3.1 服务发现流程

  1. 客户端向局域网的指定端口定期发送广播信息。
  2. 服务端在指定端口监听所有客户端的广播信息。
  3. 服务端解析接收到的广播信息,获取与客户端的通信方式(通信方式自定义,可以通过TCP协议,HTTP协议...)
  4. 以TCP协议为例,客户端发送的数据包中应该有通信端口,服务端通过该端口与客户端进行双向通信。
  5. 服务端维护已连接的客户端列表。

服务发现端 局域网 客户端 服务发现端 局域网 客户端 定期发送广播数据包 监听广播数据包 监听到广播数据包 解析数据包,获取通信端口与客户端IP 请求与客户端通信 响应服务端请求 更新客户端列表 客户端下线请求 更新客户端列表

3.2 注意点

  1. 广播的数据意味着可以被网络中所有的设备监听到,因此可以在广播数据包时做好数据加密。
  2. 在客户端与服务端进行双向连接时做身份验证
  3. 控制广播频率,如30秒一次,高频广播会占用带宽。
相关推荐
程序员清风1 小时前
程序员兼职必看:靠谱软件外包平台挑选指南与避坑清单!
java·后端·面试
皮皮林5512 小时前
利用闲置 Mac 从零部署 OpenClaw 教程 !
java
华仔啊7 小时前
挖到了 1 个 Java 小特性:var,用完就回不去了
java·后端
SimonKing8 小时前
SpringBoot整合秘笈:让Mybatis用上Calcite,实现统一SQL查询
java·后端·程序员
日月云棠1 天前
各版本JDK对比:JDK 25 特性详解
java
用户8307196840821 天前
Spring Boot 项目中日期处理的最佳实践
java·spring boot
JavaGuide1 天前
Claude Opus 4.6 真的用不起了!我换成了国产 M2.5,实测真香!!
java·spring·ai·claude code
IT探险家1 天前
Java 基本数据类型:8 种原始类型 + 数组 + 6 个新手必踩的坑
java
花花无缺1 天前
搞懂new 关键字(构造函数)和 .builder() 模式(建造者模式)创建对象
java
用户908324602731 天前
Spring Boot + MyBatis-Plus 多租户实战:从数据隔离到权限控制的完整方案
java·后端