組播(Multicast)傳輸:
在發送者和每一接收者之間實現點對多點網絡連接。
如果一台發送者同時給多個的接收者傳輸相同的數據,也只需復制一份的相同數據包。它提高了數據傳送效率。減少了骨干網絡出現擁塞的可能性。
單播、組播、廣播的差別可以看下圖:
- 單播(unicast): 是指封包在計算機網絡的傳輸中,目的地址為單一目標的一種傳輸方式。它是現今網絡應用最為廣泛,通常所使用的網絡協議或服務大多采用單播傳輸,例如一切基於TCP的協議。
- 組播(multicast): 也叫多播, 多點廣播或群播。 指把信息同時傳遞給一組目的地址。它使用策略是最高效的,因為消息在每條網絡鏈路上只需傳遞一次,而且只有在鏈路分叉的時候,消息才會被復制。
- 廣播(broadcast):是指封包在計算機網絡中傳輸時,目的地址為網絡中所有設備的一種傳輸方式。實際上,這里所說的“所有設備”也是限定在一個范圍之中,稱為“廣播域”。
判斷網卡是否支持組播
在Linux運行ifconfig, 如果網卡信息中包含UP BROADCAST RUNNING MULTICAST,則支持廣播和組播。
參考: http://colobu.com/2014/10/21/udp-and-unicast-multicast-broadcast-anycast
組播IP地址
組播IP地址用於標識一個IP組播組。
IANA(internet assigned number authority)把D類地址空間分配給IP組播,其范圍是從224.0.0.0到239.255.255.255。
- 224.0.0.0~224.0.0.255為預留的組播地址(永久組地址),地址224.0.0.0保留不做分配,其它地址供路由協議使用;
- 224.0.1.0~224.0.1.255是公用組播地址,可以用於Internet;
- 224.0.2.0~238.255.255.255為用戶可用的組播地址(臨時組地址),全網范圍內有效;
- 239.0.0.0~239.255.255.255為本地管理組播地址,僅在特定的本地范圍內有效。
參考:http://baike.baidu.com/view/492256.htm
永久的組播地址:
- 224.0.0.0 基准地址(保留)
- 224.0.0.1 所有主機的地址 (包括所有路由器地址)
- 224.0.0.2 所有組播路由器的地址
- 224.0.0.3 不分配
- 224.0.0.4 dvmrp路由器
- 224.0.0.5 所有ospf路由器
- 224.0.0.6 ospf DR/BDR
- 224.0.0.7 st路由器
- 224.0.0.8 st主機
- 224.0.0.9 rip-2路由器
- 224.0.0.10 Eigrp路由器
- 224.0.0.11 活動代理
- 224.0.0.12 dhcp 服務器/中繼代理
- 224.0.0.13 所有pim路由器
- 224.0.0.14 rsvp封裝
- 224.0.0.15 所有cbt路由器
- 224.0.0.16 指定sbm
- 224.0.0.17 所有sbms
- 224.0.0.18 vrrp
以太網傳輸單播ip報文的時候,目的mac地址使用的是接收者的mac地址。但是在傳輸組播報文時,傳輸目的不再是一個具體的接收者,而是一個成員不確定的組,所以使用的是組播mac地址。
組播mac地址是和組播ip地址對應的。iana(internet assigned number authority)規定,組播mac地址的高24bit為0x01005e,mac 地址的低23bit為組播ip地址的低23bit。
由於ip組播地址的后28位中只有23位被映射到mac地址,這樣就會有32個ip組播地址映射到同一mac地址上。
組成員機制
要將組播數據准確發送給組成員,必須先確定哪些網絡的哪些主機是組成員,只有先確定了成員的位置,才能正確轉發組播。當組成員不再需要接收組播的時候,就應該停止向成員發送組播,要確定組成員不再需要接收組播,就必須在成員退出時明確通告發送者。要確定組成員,有兩種方式:查詢和報告。
查詢,就是一台路由器向網絡中發出查詢消息,查詢是否要主機要加入組,如果有主機應答,那么路由器就可以請求上游路由器把組播流量前轉到這個子網中,如果沒有主機應答,則請求上游路由器停止向其前轉組播流量。
報告,主機也可以不必等待路由器的查詢,可以主動向路由器請求加入某個組,退出時也要向路由器發送退出消息,讓路由器停止向其前轉組播流量。
在網絡中,要確定組成員,需要使用一種協議,這種協議就是IGMP (Internet Group Management Protocol)因特網組管理協議,IGMP運行在路由器和主機之間,因為當組播發送者和組成員在不同網絡時,需要路由器為組播數據提供轉發,那么路由器就必須確認自己直連的網絡中是否存在組成員,可以使用查詢和報告來發現組成員,IGMP就可以完成這樣的工作。
參考:http://www.china-ccie.com/ccie/lilun/Multicast/Multicast.html
組播數據包的生存時間
將消息發送到多播組時,該主機和端口的所有預定接收者都將接收到消息(在數據包的生存時間范圍內,請參閱下文)。套接字不必成為多播組的成員即可向其發送消息。
多數多播包的TTL比較低: 所有的IP包都有一個“生存時間”(time-to-live),或者叫TTL。和DNS記錄不一樣,TTL指定一個包到達目的地之前跳過網絡的最大次數。單播包通常被允許穿越30個網絡(比如,被路由或”跳“過29個路由),穿過網絡通常小於15次”跳越“,所以30的限制經常用於當網絡配置的很爛時把數據包殺掉。但是許多程序發多播時把TTL設為一個很低的值,通常為0(這樣消息不會離開自身的設備)。
設置為1表示只能發到本地網絡的計算機,設置為2 表示只能穿過一個路由。很少有應用想把多播發給整個校園網絡的未知設備,更不會發給整個網絡。
諸多路由都設置了很高的TTL閾值:很多網絡路由器,特別是WAN路由和internet網關路由都有很高的TTL閾值,這樣它們就不會發送這些低TTL(如15)的多播包。這樣可以防止多播從本地網絡泄漏。
路由器一般配置成完全不發送多播,或只發一些特定的地址,或配置成阻塞多播包。
每當多播路由器轉發多播數據包時,數據包中的TTL值都會被減1,若數據包的TTL減少到0,則路由器將拋棄該數據包。TTL的值是多少,多播數據便最多能經過多少個多播路由器。例如,TTL值為0,則多播只能在本地主機的多個套接字間傳播,而不能傳播到“網線”上;TTL值為1(默認值),則多播數據遇到第一個路由器,便會被它“無情”地丟棄,不允許傳出本地網絡之外,即只有同一個網絡內的多播組成員才能收到多播數據。
Java文檔中這部分參考:http://udn.yyuap.com/doc/jdk6-api-zh/java/net/MulticastSocket.html
Java 組播的例子
MulticastSocket 是一種 (UDP) DatagramSocket,它具有加入 Internet 上其他多播主機的“組”的附加功能。
可以通過首先使用所需端口創建 MulticastSocket,然后調用 joinGroup(InetAddress groupAddr) 方法來加入多播組:
例子代碼取自:
通過 Wireshark 監控
通過 Wireshark 監控多播的請求,可以用 下面過濾條件
(eth.dst[0]&1)