| 範圍 | 用途 | 建議 |
| 224.0.0.0 ~ 224.0.0.255 | 本地鏈路範圍 (路由器不轉發) | 協定控制 (IGMP, OSPF, VRRP 等),應用層避免使用 |
| 224.0.1.0 ~ 224.0.1.255 | 公共應用保留 (IANA 分配) | NTP (224.0.1.1)、自動 RP 等,避免衝突 |
| 224.0.2.0 ~ 238.255.255.255 | 可用範圍 | 建議選用 239.x.x.x (管理範圍) 或 224.0.1.27-225 之間 |
| 239.0.0.0 ~ 239.255.255.255 | 管理範圍 (RFC 2365) | 企業內部私有使用,不洩漏至公網 |
1.3 IGMP 協定:組員管理機制
- 主機加入組 → 發送 IGMP Membership Report 至本地路由器。
- 路由器定期查詢 (Query) → 主機回應 → 維護組員狀態。
- 主機離開 → 發送 Leave Group (IGMPv2+) → 路由器查詢確認無其他成員後停止轉發。
- 多點傳送路由協定 (PIM-DM/SM, DVMRP) 負責跨網段轉發樹建立。
1.4 TTL (Time-To-Live) 控制傳播範圍
- IP 標頭欄位,每經過一層路由器遞減 1,為 0 則丟棄。
- 典型值:
1=本機, 32=同一站點, 64=地區, 128=洲際, 255=全球。
- Java API:
socket.setTimeToLive(int ttl) (0-255)。
二、Java 核心 API:MulticastSocket
// 1. 建立 Socket (綁定本地埠)
MulticastSocket socket = new MulticastSocket(5000);
// 2. 加入多點傳送組 (核心步驟)
InetAddress group = InetAddress.getByName("239.255.10.10");
socket.joinGroup(group); // 或 joinGroup(group, NetworkInterface.getByName("eth0"))
// 3. 設定參數
socket.setTimeToLive(64); // 傳播範圍
socket.setLoopbackMode(true); // 本機回環 (預設 true,發送者也收到)
socket.setReceiveBufferSize(65536); // 接收緩衝區
// 4. 發送資料
byte[] data = "Hello Multicast".getBytes(StandardCharsets.UTF_8);
DatagramPacket packet = new DatagramPacket(data, data.length, group, 5000);
socket.send(packet);
// 5. 接收資料 (阻塞)
byte[] buf = new byte[1024];
DatagramPacket recv = new DatagramPacket(buf, buf.length);
socket.receive(recv); // 解析 recv.getData(), getOffset(), getLength(), getAddress()
// 6. 離開組與關閉
socket.leaveGroup(group);
socket.close();
三、完整實戰範例:簡易多點傳送聊天室
3.1 發送端
public class MulticastSender {
public static void main(String[] args) throws Exception {
String groupIp = "239.255.10.10";
int port = 5000;
InetAddress group = InetAddress.getByName(groupIp);
try (MulticastSocket socket = new MulticastSocket()) {
socket.setTimeToLive(32); // 站點內傳播
System.out.println("輸入訊息發送 (輸入 quit 結束):");
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = in.readLine()) != null) {
if ("quit".equalsIgnoreCase(line)) break;
byte[] data = line.getBytes(StandardCharsets.UTF_8);
DatagramPacket packet = new DatagramPacket(data, data.length, group, port);
socket.send(packet);
}
}
}
}
3.2 接收端
public class MulticastReceiver {
public static void main(String[] args) throws Exception {
String groupIp = "239.255.10.10";
int port = 5000;
InetAddress group = InetAddress.getByName(groupIp);
try (MulticastSocket socket = new MulticastSocket(port)) {
socket.joinGroup(group);
System.out.println("已加入組 " + groupIp + ":" + port + ",等待訊息...");
byte[] buf = new byte[1024];
while (true) {
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
String msg = new String(packet.getData(), 0, packet.getLength(), StandardCharsets.UTF_8);
System.out.printf("[%s:%d] %s%n", packet.getAddress(), packet.getPort(), msg);
}
}
}
}
四、進階主題與避坑指南
4.1 多網卡環境指定介面
// 明確指定發送/接收網卡,避免預設路由導致資料走錯介面
NetworkInterface ni = NetworkInterface.getByName("eth0"); // 或 getByInetAddress(localIp)
socket.joinGroup(new InetSocketAddress(group, port), ni); // Java 7+
socket.setInterface(ni); // 設定發送介面
4.2 防火牆與路由器配置
- 允許 IGMP 協定 (IP 協定號 2) 通過。
- 允許 UDP 目標埠 (如 5000) 通過。
- 路由器需啟用 IGMP Snooping (L2) 或 PIM (L3) 才能正確跨網段轉發。
4.3 可靠性補償:UDP 不可靠的應對
多點傳送基於 UDP,**不保證送達、不保證順序、可能重複**。應用層需自行處理:
- 序號 + 確認/重傳機制 (如 NACK-based 可靠多點傳送)。
- 前向錯誤修正 (FEC) 編碼。
- 應用層冪等設計 (重複封包無副作用)。
4.4 安全性考量
- 無內建加密/認證,**同網段任意主機可加入組竊聽/偽造資料**。
- 敏感資料需應用層加密 (AES-GCM) + 簽名驗證 (HMAC/Ed25519)。
- 來源驗證:接收端檢查
packet.getAddress() 是否為預期發送者 (易偽造,需加密簽名)。
4.5 IPv6 多點傳送
- 地址前綴
ff00::/8,範圍位元組控制範圍 (1=介面, 2=鏈路, 4=管理, 8=站點, e=全球)。
- Java API 相同,傳入 IPv6
Inet6Address 即可。
- 組播監聽協定為 MLD (Multicast Listener Discovery),取代 IGMP。
五、應用場景總覽
| 場景 | 優勢 | 典型架構 |
| 視訊/音訊串流 | 單一來源,大量接收者,節省骨幹頻寬 | RTP over Multicast + FEC |
| 服務發現/註冊 | 客戶端廣播查詢,所有服務端回應 | UDP Multicast 查詢 + Unicast 回應 |
| 分散式快取失效 | 一條失效通知推送給所有節點 | Invalidation Event Multicast |
| 金融行情分發 | 低延遲、多訂閱者同步接收 | UDP Multicast + 可靠傳輸協定 |
| 叢集心跳/狀態同步 | 節點間狀態廣播 | 定期 Multicast 心跳封包 |
結語
Java MulticastSocket 為 IP 多點傳送提供了簡潔、跨平台的 API 封裝。掌握 D 類地址規劃、IGMP 機制、TTL 控制、網卡綁定、防火牆穿透與 UDP 不可靠性的應用層補償,是構建高效、可擴展的多點傳送應用關鍵。隨著雲原生與邊緣計算普及,多點傳送在服務發現、狀態同步、即時串流領域的價值將持續上升。
- 上一篇文章: Java 數位簽章實戰:DSA 算法實現完整指南
- 下一篇文章: J2ME 2D 遊戲開發入門:打造高效遊戲框架核心
Copyright ©
程式碼之家 All Rights Reserved