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秒一次,高频广播会占用带宽。
相关推荐
亚历克斯神21 小时前
智能搜索系统的升级复盘——从 Elasticsearch 到混合检索的检索质量提升
java·spring·微服务
m24tyy21 小时前
常见空间测绘搜索引擎介绍和使用以及子域名的收集
网络·测试工具·搜索引擎
数据安全技术观察21 小时前
数据动态脱敏:让脱敏策略跟着数据目录走
大数据·网络·数据库
金銀銅鐵21 小时前
[Java] 一个方法最多可以有多少个入参?
java·jvm
哭哭啼1 天前
JAVA服务问题诊断
java·开发语言·jvm
Sayuanni%31 天前
SpringBoot 从注解到源码:核心知识点总结
java·spring boot·后端
坚定信念,勇往无前1 天前
Maven 私有仓库-nexus
java
Minner-Scrapy1 天前
Scrapy 2.17 源码解析:Scheduler 调度器与磁盘/内存双队列
java·爬虫·python·scrapy·网络爬虫·twisted
晚风醉蝶1 天前
1-11-奇偶排序-OddEvenSort
java·数据结构·算法
夏天拐跑了西瓜1 天前
Spring Cloud 微服务实战(三):一个服务挂了,凭什么拖垮整个系统?Sentinel 限流熔断实战
java·spring cloud·微服务