Java单播、广播、多播(组播)
1. 通信方式分类
在当前网络通信中,主要存在三种通信模式:单播、广播和多播(组播)。其中多播出现时间最晚,同时兼具单播和广播的优点。
- 单播 (Unicast):单台主机与单台主机之间的通信。
- 广播 (Broadcast):单台主机与网络中的所有主机通信。
- 多播 (Multicast):单台主机与选定的一组主机通信。
2. 单播 (Unicast)
单播是网络通信中最常见的模式,网络节点之间的通信就好像人们之间的对话。如果一个人对另外一个人说话,用网络术语描述即为“单播”,此时信息的接收和传递只在两个节点之间进行。
2.1 单播的优点
- 服务器能够响应客户端的请求。
- 服务器能针对每个客户端的不同请求发送不同的响应,容易实现个性化服务。
2.2 单播的缺点
服务器需要针对每个客户机发送数据流。服务器总流量 = 客户机数量 × 客户机流量。在客户数量大、每个客户机流量大的流媒体应用中,服务器容易不堪重负。
2.3 应用场景
单播在网络中得到了广泛的应用,网络上绝大部分的数据都是以单播的形式传输的。例如:收发电子邮件、浏览网页时,必须与邮件服务器、网站服务器建立连接,此时使用的就是单播通信方式。
3. 广播 (Broadcast)
“广播”可以比喻为:一个人通过广播喇叭对在场的全体说话(不管对方是否乐意听)。换句话说,广播是一台主机对某一个网络上的所有主机发送数据报包。这个网络可能是整个网络,也可能是子网,还有可能是所有子网。
广播主要分为两类:本地广播和定向广播。
- 定向广播:将数据报包发送到本网络之外的特定网络的所有主机。由于互联网上的大部分路由器都不转发定向广播消息,此处不再深入介绍。
- 本地广播:将数据报包发送到本地网络的所有主机。IPv4 的本地广播地址为
255.255.255.255,路由器不会转发此广播。
3.1 广播的优点
- 通信效率高,信息可以一次性传递到某一个网络上的所有主机。
- 服务器不用向每个客户端单独发送数据,因此服务器负载较低。
3.2 广播的缺点
- 非常占用网络带宽。
- 缺乏针对性,不管主机是否真的需要接收该数据,都会强制接收。
3.3 应用场景
有线电视就是典型的广播型网络。
Java 广播示例:
客户端发送程序
// 发送端程序
public class BroadcastTest {
public static void main(String[] args) {
// 广播的实现:由客户端发出广播,服务器端接收
String host = "255.255.255.255"; // 广播地址
int port = 9999; // 广播的目的端口
String message = "test"; // 用于发送的字符串
try {
InetAddress adds = InetAddress.getByName(host);
DatagramSocket ds = new DatagramSocket();
DatagramPacket dp = new DatagramPacket(message.getBytes(), message.length(), adds, port);
ds.send(dp);
ds.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}服务器端接收程序
// 服务器端接收程序
public class BroadcastServer {
public static void main(String[] args) {
int port = 9999; // 开启监听的端口
DatagramSocket ds = null;
DatagramPacket dp = null;
byte[] buf = new byte[1024]; // 存储发来的消息
StringBuffer sbuf = new StringBuffer();
try {
// 绑定端口
ds = new DatagramSocket(port);
dp = new DatagramPacket(buf, buf.length);
System.out.println("监听广播端口打开:");
ds.receive(dp);
ds.close();
int i;
for (i = 0; i < 1024; i++) {
if (buf[i] == 0) {
break;
}
sbuf.append((char) buf[i]);
}
System.out.println("收到广播消息:" + sbuf.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}4. 多播/组播 (Multicast)
“组播”可以比喻为:你对着大街喊:“是男人的来一下,一人发一百块”。那么男的会过来,女的就不会过来,因为没有钱发她不理你(组播中所有的男生就是一个组)。
换句话说,组播是一台主机向指定的一组主机发送数据报包。如果采用单播方式,逐个节点传输,有多少个目标节点就会有多少次传送过程,效率极低;如果采用不区分目标、全部发送的广播方式,虽然一次可以传送完数据,但达不到区分特定数据接收对象的目的,且会占用网络带宽。采用组播方式,既可以实现一次传送所有目标节点的数据,也可以达到只对特定对象传送数据的目的。
IP 网络的组播一般通过组播 IP 地址来实现。组播 IP 地址就是 D 类 IP 地址,即 224.0.0.0 至 239.255.255.255 之间的 IP 地址。
4.1 组播的优点
- 具备广播所具备的所有优点。
- 与单播相比,提高了发送数据报包的效率;与广播相比,减少了网络流量。
4.2 组播的缺点
- 与单播协议相比没有纠错机制,发生丢包错包后难以弥补,但可以通过一定的容错机制和 QoS 加以弥补。
组播的简单示例:
客户端发送消息
// 发送端程序
public class SendUdp {
public static void main(String[] args) throws IOException {
MulticastSocket ms = null;
DatagramPacket dataPacket = null;
ms = new MulticastSocket();
ms.setTimeToLive(32);
// 将本机的 IP 地址放到数据包里,其实 server 端接收到数据包后也能获取到发包方的 IP 的
byte[] data = "组播 测试".getBytes();
InetAddress address = InetAddress.getByName("239.0.0.255");
dataPacket = new DatagramPacket(data, data.length, address, 8899);
ms.send(dataPacket);
ms.close();
}
}服务器端接收程序
// 服务器端程序
public class TestMain {
private static MulticastSocket ds;
static String multicastHost = "239.0.0.255";
static InetAddress receiveAddress;
public static void main(String[] args) throws IOException {
ds = new MulticastSocket(8899);
receiveAddress = InetAddress.getByName(multicastHost);
ds.joinGroup(receiveAddress);
new Thread(new udpRunnable(ds)).start();
}
}
class udpRunnable implements Runnable {
MulticastSocket ds;
public udpRunnable(MulticastSocket ds) {
this.ds = ds;
}
public void run() {
byte buf[] = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, 1024);
while (true) {
try {
ds.receive(dp);
System.out.println("receive client message : " + new String(buf, 0, dp.getLength()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}运行结果截图:

5. 参考资料
说明
- 代码版本:文中示例代码采用较早的 Java 风格(未使用 try-with-resources 语法),适用于理解原理,实际生产环境建议结合 Java 7+ 特性优化资源管理。
- 网络环境:多播/组播功能依赖网络设备(路由器、交换机)的支持,部分局域网或云服务器环境可能默认禁止组播流量,测试时请确保网络配置允许。
版权声明:本文为原创文章,版权归 戴老师的博客 所有,转载请联系博主获得授权。
本文地址:https://1diff.fun/archives/java-dan-bo--guang-bo--duo-bo--zu-bo.html
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。