午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

TCP/IP詳解 第九章 IP組播基礎(chǔ)及工作原理

 yzdszy 2021-06-02

轉(zhuǎn)載請聲明博主:https://blog.csdn.net/caofengtao1314/article/details/106496059

一、尋址模式

①尋址模式—概述

在計算機網(wǎng)絡(luò)中,尋址模式是指我們?nèi)绾螌ぶ肪W(wǎng)絡(luò)上的主機的機制。 

IPv4和IPv6提供幾種類型的模式,通過這些模式可以尋址單個主機,可

以一次尋址多于一個主機,或者可以尋址最近距離的主機。

有些書籍也將尋址模式稱作IP網(wǎng)絡(luò)的數(shù)據(jù)傳輸方式

 

②尋址模式—單播

在單播尋址模式下,IP地址接是網(wǎng)段中唯一標(biāo)識。 IP數(shù)據(jù)包包含源IP地址和目標(biāo)IP地址。 主機接口配備有在該網(wǎng)段中唯一的IP地址。 網(wǎng)絡(luò)交換機或路由器在接收到指定到單個主機的單播IP分組時,發(fā)送到其連接到該特定主機的其輸出接口之一。

③尋址模式—廣播

廣播的定義:

       主機之間“一對所有”的通信模式,網(wǎng)絡(luò)對其中每一臺主機發(fā)送信號都進行無條件復(fù)制并轉(zhuǎn)發(fā),所有主機都可以接收到所有信息(不管你是否需要),由于其不用路徑選擇,所以其網(wǎng)絡(luò)成本很低廉。有線電視網(wǎng)就是典型的廣播型網(wǎng)絡(luò),我們的電視機實際上是接收到所有頻道的信號,但只將一個頻道信號還原成畫面。在數(shù)據(jù)網(wǎng)絡(luò)中也允許廣播的存在,但其被限制在二層交換機的局域網(wǎng)范圍內(nèi),禁止廣播數(shù)據(jù)穿過路由器,防止廣播數(shù)據(jù)影響大面積的主機。

廣播的缺點:

1、無法針對每個客戶的要求和時間及時提供個性化服務(wù)。

2、廣播禁止在Internet寬帶網(wǎng)上傳輸。

3、網(wǎng)絡(luò)允許提供數(shù)據(jù)的寬帶有限,客戶端的最大寬帶等于服務(wù)總寬帶。如

      有線電視的客戶端的線路支持100個頻道(如果采用數(shù)字壓縮技術(shù),理論

      上可以提供500個頻道),即使服務(wù)商有更大的財力配置更多的發(fā)送設(shè)備、

      改成光纖主干,也無法超越此極限。也就是說無法向眾多客戶提供更多

      樣化、更加個性化的服務(wù)。

4、IPv6已經(jīng)禁止使用廣播

廣播的優(yōu)點:

網(wǎng)絡(luò)設(shè)備簡單,維護簡單,布網(wǎng)成本低廉。

廣播的應(yīng)用:

1、ARP協(xié)議通過鏈路層廣播定位具有IP地址的主機的MAC地址

2、主機通過廣播向DHCP服務(wù)器申請IP地址

④尋址模式—組播

IPv6組播模式與IPv4相同。 目的地為多個主機的數(shù)據(jù)包在特殊的多播地址上發(fā)送。 所有對該組播信息感興趣的主機需要首先加入該組播組。 所有加入組的接口接收組播報文并處理,其他對組播報文不感興趣的主機忽略組播信息。

組播的優(yōu)點:

 1 、發(fā)送方僅發(fā)一份數(shù)據(jù)包,此后數(shù)據(jù)包只是在需要復(fù)制分發(fā)的地方才會被復(fù)制分發(fā),每一網(wǎng)段中都將保持只有一份數(shù)據(jù)流,減輕服務(wù)器的負擔(dān),節(jié)省網(wǎng)絡(luò)帶寬。

 2 、由于組播協(xié)議是根據(jù)接受者的需要對數(shù)據(jù)流進行接收,所以服務(wù)端的服務(wù)總帶寬不受客戶接入端帶寬的限制。 IP 協(xié)議允許有 2 億 6 千多萬個組播,所以其提供的服務(wù)可以非常豐富。

 3 、此協(xié)議和單播協(xié)議一樣允許在 Internet 寬帶網(wǎng)上傳輸。

組播的缺點:

組播是基于UDP的。

盡力投遞:報文丟失是不可避免的。因此組播應(yīng)用程序不能依賴組播網(wǎng)絡(luò)進行可靠性保證,必須針對組播網(wǎng)絡(luò)的這個特點進行特別設(shè)計。“可靠組播”目前仍然處于研究階段。

沒有擁塞避免機制:缺少TCP窗口機制和慢啟動機制,組播可能會出現(xiàn)擁塞。如果可能的話,組播應(yīng)用程序應(yīng)該嘗試檢測并避免擁塞。

報文重復(fù):某些組播協(xié)議的特殊機制(如Assert機制和SPT切換機制)可能會造成偶爾的數(shù)據(jù)包的重復(fù)。組播應(yīng)用程序應(yīng)該容忍這種現(xiàn)象。

報文失序:同樣組播協(xié)議有的時候會造成報文到達的次序錯亂,組播應(yīng)用程序必須自己采用某種手段進行糾正(比如緩沖池機制等)。

組播應(yīng)用

組播應(yīng)用大致可以分為三類: 點對多點應(yīng)用,多點對多點應(yīng)用和多點對點應(yīng)用。

組播應(yīng)用--點對多點

點對多點應(yīng)用是指一個發(fā)送者,多個接收者的應(yīng)用形式,這是最常見的組播應(yīng)用形式。

媒體廣播:如演講、演示、會議等按日程進行的事件。其傳統(tǒng)媒體分發(fā)手段通常采用電視和廣播。

媒體推送:如新聞標(biāo)題、天氣變化、運動比分等一些非商業(yè)關(guān)鍵性的動態(tài)變化的信息。

信息緩存: 如網(wǎng)站信息、執(zhí)行代碼和其他基于文件的分布式復(fù)制或緩存更新。

事件通知:如網(wǎng)絡(luò)時間、組播會話日程、隨機數(shù)字、密鑰、配置更新、有效范圍的網(wǎng)絡(luò)警報或其他有用信息。

狀態(tài)監(jiān)視:如股票價格、傳感設(shè)備、安全系統(tǒng)、生產(chǎn)信息或其他實時信息多點對多點

組播應(yīng)用--多點對多點

多點對多點應(yīng)用是指多個發(fā)送者和多個接收者的應(yīng)用形式。通常,每個接收者可以接收多個發(fā)送者發(fā)送的數(shù)據(jù),同時,每個發(fā)送者可以把數(shù)據(jù)發(fā)送給多個接收者。

典型應(yīng)用包括:

多點會議:通常音/視頻和白板應(yīng)用構(gòu)成多點會議應(yīng)用。

協(xié)同處理:如共享文檔的編輯。

遠程學(xué)習(xí):這實際上是媒體廣播應(yīng)用加上對上行數(shù)據(jù)流(允許學(xué)生向老師提問)的支持。

討論組:類似于基于文本的多點會議,還可以提供一些模擬的表達。

分布式交互模擬(DIS):它對帶寬和時延的要求較高。

多人游戲:多人游戲是一種帶討論組能力的簡單分布式交互模擬。它對帶寬和時延的要求都比較高。

Jam Session:這是一種音頻編碼共享應(yīng)用。它對帶寬和時延的要求都比較高。

組播應(yīng)用--多點對點

多點對點應(yīng)用是指多個發(fā)送者,一個接收者的應(yīng)用形式。通常是雙向請求響應(yīng)應(yīng)用,任何一端(多點或點)都有可能發(fā)起請求。典型應(yīng)用包括:

資源查找:如服務(wù)定位,它要求的帶寬較低,對時延的要求一般。

數(shù)據(jù)收集:它是點對多點應(yīng)用中狀態(tài)監(jiān)視應(yīng)用的反向過程。它可能由多個傳感設(shè)備把數(shù)據(jù)發(fā)回給一個數(shù)據(jù)收集主機。

網(wǎng)絡(luò)竟拍:拍賣者拍賣產(chǎn)品,而多個竟拍者把標(biāo)價發(fā)回給拍賣者。

信息詢問: 詢問者發(fā)送一個詢問,所有被詢問者返回應(yīng)答。

Juke Box:如支持準(zhǔn)點播(Near-On-Demand)的音視頻倒放。通常接收者采用“帶外的”協(xié)議機制(如HTTP、RTSP、SMTP,也可以采用組播方式)發(fā)送倒放請求給一個調(diào)度隊列。它對帶寬的要求較高,對延時的要求一般。

⑤尋址模式—任播

IPv6引入了一種新型的尋址,稱為Anycast尋址。 在此尋址模式下,多個接口(主機)被分配相同的任播IP地址。 當(dāng)主機希望與配備有Anycast IP地址的主機通信時,發(fā)送單播消息。 在復(fù)雜的路由機制的幫助下,在路由成本方面,該單播消息被遞送到最接近發(fā)送方的主機。

讓我們以一個位于所有大陸的TutorialPoints.com Web服務(wù)器為例。 假設(shè)所有Web服務(wù)器都分配有單個IPv6 Anycast IP地址。 現(xiàn)在,當(dāng)歐洲的用戶希望訪問TutorialsPoint.com時,DNS指向物理上位于歐洲的服務(wù)器。 如果來自印度的用戶嘗試訪問Tutorialspoint.com,則DNS將指向僅位于亞洲的Web服務(wù)器。最接近或最接近的術(shù)語用于路由成本。

在上圖中,當(dāng)客戶端計算機嘗試訪問服務(wù)器時,請求轉(zhuǎn)發(fā)到具有最低路由開銷的服務(wù)器。

二、組播詳解

①組播方式數(shù)據(jù)傳輸示意圖

②組播基本概念

組播傳輸?shù)奶攸c是一點發(fā)出,多點接收。如組播方式數(shù)據(jù)傳輸示意圖,網(wǎng)絡(luò)中存在信息發(fā)送源Source,感興趣的用戶HostA和HostC提出信息需求,Source發(fā)出的數(shù)據(jù)只有HostA和HostC會接收到。

在組播通信中,需要理解以下幾個重要的基本概念。

1、組播組:用組播IP地址進行標(biāo)識的一個集合,是一個組播成員的集合,各組播成員共享這一個組播組IP地址。

2、組播源:以組播組IP地址為目的地址(組播源配置的也是單播IP地址),發(fā)送IP報文的信源稱為組播源。但組播源通常不需要加入組播組,否則自己接收自己發(fā)送出去的數(shù)據(jù)了。上圖中的Source就是一個組播源。一個組播源可以同時向多個組播組發(fā)送數(shù)據(jù),多個組播源也可以同時向一個組播組發(fā)送報文。

3、組播組成員:所有加入某組播組的主機便成為該組播組的成員。如上圖中的HostA和HostC。組播組中的成員是動態(tài)的,主機可以在任何時刻加入或離開組播組。組播組成員可以廣泛地分布在網(wǎng)絡(luò)中的任何地方。

4、組播路由器:支持三層組播功能的路由器或三層交換機(它們不是組播組成員),如上圖中的各個Router。組播路由器不僅能夠提供組播路由功能,也能夠在與用戶連接的末梢網(wǎng)段上提供組播組成員的管理功能。

③典型IP組播模型

根據(jù)對組播源處理方式的不同,IP組播模型有下列3種:

ASM(Any-SourceMulticast,任意源組播)

SFM(Source-Filtered Multicast,過濾源組播)

SSM(Source-SpecificMulticast,指定源組播)

1、ASM模型

      簡單說,ASM(任意源組播)模型就是任意源都可以成為組播源。由此可知,ASM模型中的組播源是不限定的,任意一個發(fā)送者都可以成為組播源,然后向某組播組地址發(fā)送數(shù)據(jù),顯然安全性較差。接收者通過加入對應(yīng)的組播組就可以獲得發(fā)往改組播組的任意組播數(shù)據(jù),而且接收者無法預(yù)先知道組播源的位置,但可以在任意時間加入或離開該組播組。為提高安全性,可以在路由器上配置針對組播源的過濾策略,允許或禁止來自某些組播源的報文通過。最終從接收者角度看,數(shù)據(jù)是經(jīng)過篩選的。

      ASM模型中組播組可以使用的組播IP地址為224.0.1.0~231.255.255.255、233.0.0.0~238.255.255.255。但要求組播組地址必須整個組播網(wǎng)絡(luò)中唯一?!拔ㄒ弧敝傅氖峭粫r刻一個ASM組播組地址只能被一種組播應(yīng)用使用。如果有兩種不同的應(yīng)用程序使用了同一個ASM組播組地址發(fā)送數(shù)據(jù),它們的接收者會同時收到來自兩個源的數(shù)據(jù)。這樣一方面會導(dǎo)致網(wǎng)絡(luò)流量擁塞,另一方面也會給接收者主機造成困擾

2、SFM模型

      SFM(過濾源組播)模型繼承了ASM模型,從發(fā)送者角度來看兩者的組播組成員關(guān)系完全相同,也可以是任意組播源。但是,在SFM模型中組播上層應(yīng)用軟件可以根據(jù)收到的組播包的源IP地址進行過濾,允許或禁止來自某些組播源的包通過。這樣一來,接收者就可以只接收允許通過的組播源發(fā)送來的組播數(shù)據(jù)。即SFM在ASM的基礎(chǔ)上添加了組播源過濾策略。

3、SSM模型

      現(xiàn)實生活中,用戶可能只對某些組播源發(fā)送的組播數(shù)據(jù)感興趣,而不愿接收其他源發(fā)送的數(shù)據(jù)。SSM(指定源組播)模型就是一種為用戶提供能夠在客戶端指定組播源的傳輸服務(wù)。SSM模型與ASM模型的根本區(qū)別在于:SSM模型中的接收者已經(jīng)通過其他手段預(yù)先知道了所需接收組播數(shù)據(jù)的組播源的具體位置,限定了可接收的組播源。然后,SSM模型使用與ASM/SFM模型不同的組播組地址范圍(為232.0.0.0~232.255.255.255)直接在接收者和其指定的組播源之間建立專用的組播轉(zhuǎn)發(fā)樹。

④IP組播地址

由于組播數(shù)據(jù)的接收者是一個組播組內(nèi)的多個主機,因此,需要面對數(shù)據(jù)源該將數(shù)據(jù)發(fā)往何處、目的地址如何選取的問題,就是組播尋址。與單播中的IP尋址或者MAC尋址一樣,為了讓組播源和組播成員進行通信,需要提供網(wǎng)絡(luò)層組播地址,即IP組播地址。同時必須存在一種技術(shù)將IP組播地址映射為鏈路層MAC組播地址

注意:不要認為在IP組播中所有組播設(shè)備上的IP地址都是使用組播地址。實際上只有組播組IP地址是組播IP地址,而像組播源、接收者主機的IP地址仍是單播IP地址

1、三層組播IP地址

根據(jù)IANA(InternetAssigned Numbers Authority,因特網(wǎng)編號授權(quán)委員會)規(guī)定,IP地址分為五類:即A類、B類、C類、D類和E類。

單播包按照網(wǎng)絡(luò)規(guī)模大小分別使用A、B、C三類IP地址。

組播包的目的地址使用DIP地址,D類地址不能出現(xiàn)在IP包的源IP地址字段(也就是不能作為組播源地址,換言之,組播源的IP地址仍是單播地址)。

E類地址保留以后使用。

在單播數(shù)據(jù)傳輸過程中,一個數(shù)據(jù)包傳輸?shù)穆窂绞菑脑吹刂仿酚傻侥康牡刂罚谩爸鹛╤op-by-hop)”的原理在IP網(wǎng)絡(luò)中傳輸。然而在IP組播環(huán)境中,數(shù)據(jù)包的目的地不是一個,而是一組,形成組地址(可理解為所有接收者的單播地址與一個組播組地址形成了映射關(guān)系)。所有的數(shù)據(jù)接收者都加入一個組內(nèi),并且一旦加入之后,流向該組地址的數(shù)據(jù)立即向接收者傳輸,組中的所有成員都能接收到數(shù)據(jù)包,這個組就是“組播組”。

組播組具有以下幾個特點:

(1)組播組中的成員是動態(tài)的,主機可以在任何時刻加入或離開組播組。

(2)組播組可以是永久的也可以是臨時的。

(3)由IANA分配組播組地址的組播組稱為永久組播組(又稱保留組播組)。

對于永久組播組,要注意以下幾點:

(1)永久組播組的IP地址保持不變,但組中的成員構(gòu)成可以發(fā)生變化。

(2)永久組播組中成員的數(shù)量可以是任意的,甚至可以是零。

(3)那些沒有保留下來供永久組播組使用的IP組播地址,可以被臨時組播組使用。

2、二層以太網(wǎng)組播MAC地址

       以太網(wǎng)傳輸單播IP包的時候,目的MAC地址使用的是接收者的MAC地址。但是在傳輸組播包時,傳輸目標(biāo)不再是一個具體的接收者,而是一個成員不確定的組,所以對應(yīng)也就需要使用組播MAC地址作為目的地址。

     IANA規(guī)定,組播MAC地址的高25位固定為0000 00010000 0000 0101 1110 0,形成MAC地址25位前綴,MAC地址的低23位為組播IPv4地址的低23位。它們之間的映射關(guān)系如下圖(組播IPv4地址中的低23位映射到組播MAC地址的低23位)

由于IPv4組播地址的高4位是1110,代表組播標(biāo)識,而低28位中只有23位被映射到MAC地址,這樣IP地址中就會有5位數(shù)據(jù)丟失,直接的結(jié)果是出現(xiàn)了32(2的5次方)個IP組播地址映射到同一組播MAC地址上。

 IPv6組播MAC地址的高16位為0x3333,低32位是從IPv6組播地址的低32位映射過來的。如下圖IPv6組播地址FF1E::F30E:101的MAC地址映射:

組播抓包

要實現(xiàn)一套完整的組播服務(wù),需要在網(wǎng)絡(luò)各個位置部署多種組播協(xié)議相互配合,共同運作。不同結(jié)構(gòu)的組播網(wǎng)絡(luò)所需使用的組播協(xié)議不完全一樣。

        下圖是一個典型的單PIM域組播網(wǎng)絡(luò)示意圖,整個組播網(wǎng)絡(luò)是由路由器或三層交換機+二層交換機組成的。

        從圖中可以看出在這些組播設(shè)備上運行的組播協(xié)議包括PIM(協(xié)議無關(guān)組播,同時由IPv4和IPv6版本)、IPv4網(wǎng)絡(luò)的IGMP(因特網(wǎng)組管理協(xié)議),IPv6網(wǎng)絡(luò)中的MLD(組播監(jiān)聽器發(fā)現(xiàn))、IPv4網(wǎng)絡(luò)的IGMP Snooping(因特網(wǎng)組管理協(xié)議嗅探),IPv6網(wǎng)絡(luò)中的MLD Snooping(組播監(jiān)聽器發(fā)現(xiàn)嗅探)。

⑤IP組播路由表維護協(xié)議簡介

要實現(xiàn)一套完整的組播服務(wù),需要在網(wǎng)絡(luò)各個位置部署多種組播協(xié)議相互配合,共同運作。不同結(jié)構(gòu)的組播網(wǎng)絡(luò)所需使用的組播協(xié)議不完全一樣。

        下圖是一個典型的單PIM域組播網(wǎng)絡(luò)示意圖,整個組播網(wǎng)絡(luò)是由路由器或三層交換機+二層交換機組成的。

下圖12-7是一個跨PIM-SM域的組播網(wǎng)絡(luò)示意圖,與上圖所示的單PIM域組播網(wǎng)絡(luò)相比,在運行的組播協(xié)議上僅需在PIM域邊界組播路由器上多了一個實現(xiàn)跨PIM域連接的MSDP(組播源發(fā)現(xiàn)協(xié)議)。而12-8是一個跨AS域組播網(wǎng)絡(luò)示意圖,與12-7所示的跨PIM域組播網(wǎng)絡(luò)相比,在運行的組播協(xié)議又僅需在AS邊界組播路由器上多了一個用于不同AS組播連接的MBGP(組播邊界管理協(xié)議)。

1、IGMP和MLD

在IP組播傳輸模型中,發(fā)送者不關(guān)心接收者所處的位置,只要將數(shù)據(jù)發(fā)送到約定的目的地址,剩下的工作就交給網(wǎng)絡(luò)去完成。網(wǎng)絡(luò)中的路由器設(shè)備必須收集接收者的信息,并按照正確的路徑實現(xiàn)組播報文的轉(zhuǎn)發(fā)和復(fù)制。

接收者信息的收集和管理的工作通過IGMP(InternetGroup Management Protocol,因特網(wǎng)組管理協(xié)議)或MLD(Multicast Listener Discovery,組播監(jiān)聽器發(fā)現(xiàn))協(xié)議來完成的。其中,IGMP用于IPv4網(wǎng)絡(luò),MLD用于IPv6網(wǎng)絡(luò)。用于為主機側(cè)提供組播組成員動態(tài)加入與離開服務(wù),為路由器側(cè)提供組成員關(guān)系的維護與管理服務(wù),同時與上層組播路由協(xié)議進行信息交互。

IGMP包含3個版本,分別是IGMPv1、IGMPv2和IGMPv3。新版本完全兼容舊版本。目前應(yīng)用最廣泛的是IGMPv2。在組播模型方面,3個版本都支持ASM模型;IGMPv3可以直接支持SSM模型,而IGMPv1和IGMPv2需要結(jié)合SSMMapping技術(shù)才能支持SSM模型。

在IPv6組播中使用MLD協(xié)議來替代IGMP協(xié)議,也是一種三層組播協(xié)議。MLD包含兩個版本,分別是MLDv1和MLDv2。MLDv1的功能與IGMPv2相似;MLDv2的功能與IGMPv3相似。兩個MLD版本都支持ASM模型;MLDv2可以直接支持SSM模型,而MLDv1需要結(jié)合SSM-Mapping技術(shù)才能支持SSM模型。

2、IGMPSnooping和MLD SnoopingIGMP

Snooping和MLD Snooping協(xié)議是運行在組播路由器和用戶主機之間的二層交換機上的二層組播協(xié)議,配置在VLAN內(nèi)。其中,IGMP Snooping用于IPv4網(wǎng)絡(luò),MLD Snooping用于IPv6網(wǎng)絡(luò),用來偵聽路由器和主機之間發(fā)送的IGMP、MLD報文建立組播數(shù)據(jù)的二層轉(zhuǎn)發(fā)表,從而管理和控制組播數(shù)據(jù)在二層網(wǎng)絡(luò)中的轉(zhuǎn)發(fā)。

3、PIM和MSDP

       組播報文轉(zhuǎn)發(fā)路徑的建立,有多種組播路由協(xié)議可以完成。目前應(yīng)用廣泛的是PIM(Protocol Independent Multicast,協(xié)議無關(guān)組播)協(xié)議。PIM是一種域內(nèi)組播路由協(xié)議,當(dāng)跨PIM域傳遞組播源信息時,需要MSDP(Multicast Source Discovery Protocol,組播源發(fā)現(xiàn)協(xié)議)支持;當(dāng)跨AS域建立組播路由時則同時需要MSDP和MBGP(MultiProtocolBorder Gateway Protocol,組播邊界網(wǎng)關(guān)協(xié)議)支持。

       PIM是用于IPv4或IPv6組播網(wǎng)絡(luò)中域內(nèi)組播路由器之間的組播路由與轉(zhuǎn)發(fā),用來在自治系統(tǒng)AS內(nèi)發(fā)現(xiàn)組播源并構(gòu)建組播分發(fā)樹,將信息傳遞到接收者。在一個小型網(wǎng)絡(luò)中,所有的組播路由器都在一個PIM組播域內(nèi)。他可以動態(tài)響應(yīng)網(wǎng)絡(luò)拓撲變化,維護組播路由表,并按照路由表項執(zhí)行轉(zhuǎn)發(fā)。

       MSDP目前僅用于IPv4組播網(wǎng)絡(luò)中域間組播路由器之間的域間組播源信息共享,但只對ASM服務(wù)模型有意義。它可以實現(xiàn)源所在域內(nèi)的路由器將本地源信息傳播給其他域內(nèi)的路由器,以及不同域的路由器之間傳遞源信息。為了使不同的PIM-SM域之間組播數(shù)據(jù)能夠互通,需要在域間部署MSDP協(xié)議。MSDP通過在各個PIM-SM域之間建立MSDP對等體關(guān)系,對等體之間交互SA(Source Active,源激活)消息來傳遞組播信息,從而實現(xiàn)接收者主機可以接收其他PIM-SM域的組播源數(shù)據(jù)。

4、 RPF檢查

在單播路由與轉(zhuǎn)發(fā)中,單播報文是沿著一條點到點的路徑傳輸?shù)?,路由器只需考慮報文需要到達的位置(即目的地址),就知道應(yīng)該從哪個接口轉(zhuǎn)發(fā)出去。組播路由與轉(zhuǎn)發(fā)則不同,因為組播報文的目的地址為組播地址,只是標(biāo)識了一組接收者,并不是一個可以唯一確定其位置的IP地址,所以無法通過“目的地址”來找到接收者的位置。但是組播報文的來源位置(即源地址)是可以確定的,所以組播報文的轉(zhuǎn)發(fā)路徑可根據(jù)其源地址的逆向查找來確保轉(zhuǎn)發(fā)路徑的正確性。具體過程如下:

(1)組播路由器在收到一份組播報文后,會根據(jù)報文的源地址通過單播路由表查找到達“報文源”的路由,查看到“報文源”的路由表的出接口是否與收到該組播報文的入接口一致。

(2)如果一致,則認為該組播報文是從正確的接口到達,從而保證了整個轉(zhuǎn)發(fā)路徑的正確性和唯一性。

(3)如果不一致,則認為該組播報文非法,將被直接丟棄。

(4)在RPF檢查的過程中除依據(jù)單播路由表外,還會依據(jù)MBGP路由表、組播靜態(tài)路由表。且缺省情況下,組播靜態(tài)路由、MBGP路由和單播路由的優(yōu)先級是依次降低的

三、組播socket編程

Linux接收端多播編程步驟:

1. 建立一個 socket
2. 設(shè)置多播的參數(shù),例如超時時間 TTL ,本地回環(huán)許可 LOOP 等
3. 加入多播 組
4. 發(fā)送和接收 數(shù)據(jù)
5. 從多播組 離開

Linux發(fā)送端多播編程步驟:

1.建立一個socket;

2.指定組播數(shù)據(jù)輸出網(wǎng)口

3.向指定組播地址和端口號發(fā)送數(shù)據(jù)

如果不使用這個函數(shù)那么就需要通過路由表來操作數(shù)據(jù)從哪個網(wǎng)口出去

multicast_rcv.c

  1. /*
  2. *broadcast_client.c - 多播的客戶端
  3. */
  4. #include<stdio.h>
  5. #include<stdlib.h>
  6. #include<string.h>
  7. #include<unistd.h>
  8. #include<sys/types.h>
  9. #include<sys/socket.h>
  10. #include<arpa/inet.h>
  11. #include<netinet/in.h>
  12. #define MCAST_PORT 8888
  13. #define MCAST_ADDR '224.0.0.100' /*一個局部連接多播地址,路由器不進行轉(zhuǎn)發(fā)*/
  14. #define MCAST_INTERVAL 5 /*發(fā)送間隔時間*/
  15. #define BUFF_SIZE 3000 /*接收緩沖區(qū)大小*/
  16. int main(int argc, char*argv[])
  17. {
  18. int s; /*套接字文件描述符*/
  19. struct sockaddr_in local_addr; /*本地地址*/
  20. struct sockaddr_in client_addr; /*本地地址*/
  21. int err = -1;
  22. s = socket(AF_INET, SOCK_DGRAM, 0); /*建立套接字*/
  23. if (s == -1)
  24. {
  25. perror('socket()');
  26. return -1;
  27. }
  28. /*初始化地址*/
  29. memset(&local_addr, 0, sizeof(local_addr));
  30. local_addr.sin_family = AF_INET;
  31. local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  32. local_addr.sin_port = htons(MCAST_PORT);
  33. /*綁定socket*/
  34. err = bind(s,(struct sockaddr*)&local_addr, sizeof(local_addr)) ;
  35. if(err < 0)
  36. {
  37. perror('bind()');
  38. return -2;
  39. }
  40. /*設(shè)置回環(huán)許可*/
  41. int loop = 1;
  42. err = setsockopt(s,IPPROTO_IP, IP_MULTICAST_LOOP,&loop, sizeof(loop));
  43. if(err < 0)
  44. {
  45. perror('setsockopt():IP_MULTICAST_LOOP');
  46. return -3;
  47. }
  48. struct ip_mreq mreq; /*加入多播組*/
  49. mreq.imr_multiaddr.s_addr = inet_addr(MCAST_ADDR); /*多播地址*/
  50. //mreq.imr_interface.s_addr = htonl(INADDR_ANY); /*網(wǎng)絡(luò)接口為默認*/
  51. /*將本機加入多播組*/
  52. err = setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreq, sizeof
  53. (mreq));
  54. if (err < 0)
  55. {
  56. perror('setsockopt():IP_ADD_MEMBERSHIP');
  57. return -4;
  58. }
  59. int times = 0;
  60. int addr_len = 0;
  61. char buff[BUFF_SIZE];
  62. int n = 0;
  63. /*循環(huán)接收多播組的消息,5次后退出*/
  64. for(times = 0;times<30000;times++)
  65. {
  66. addr_len = sizeof(client_addr);
  67. memset(buff, 0, BUFF_SIZE); /*清空接收緩沖區(qū)*/
  68. memset(&client_addr,0,sizeof(client_addr));
  69. /*接收數(shù)據(jù)*/
  70. n = recvfrom(s, buff, BUFF_SIZE, 0,(struct sockaddr*)&client_addr,&addr_len);
  71. if( n== -1)
  72. {
  73. perror('recvfrom()');
  74. }
  75. /*打印信息*/
  76. printf('Recv %dst message from server:%s #######recvfrom btytes=%d\n', times, buff,n);
  77. printf('client ip:0x%x port:0x%x\n',local_addr.sin_addr.s_addr,local_addr.sin_port);
  78. //sleep(MCAST_INTERVAL);
  79. }
  80. /*退出多播組*/
  81. err = setsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP,&mreq, sizeof
  82. (mreq));
  83. close(s);
  84. return 0;
  85. }

multicast_send.c

/**broadcast_server.c - 多播服務(wù)程序*/#include<stdio.h>#include<stdlib.h>  #include<string.h>     #include<unistd.h>      #include<sys/types.h>    #include<sys/socket.h>     #include<arpa/inet.h>    #include<netinet/in.h> #define MCAST_PORT 8888#define MCAST_ADDR '224.0.0.100'    /*一個局部連接多播地址,路由器不進行轉(zhuǎn)發(fā)*/#define MCAST_DATA 'BROADCAST TEST DATA11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111zz'            /*多播發(fā)送的數(shù)據(jù)*/#define MCAST_INTERVAL 1                            /*發(fā)送間隔時間*/int main(int argc, char*argv){int s;struct sockaddr_in mcast_addr;     s = socket(AF_INET, SOCK_DGRAM, 0);         /*建立套接字*/char buf[1024];int i = 0;if (s == -1){perror('socket()');return -1;}memset(&mcast_addr, 0, sizeof(mcast_addr));     /*初始化IP多播地址為0*/mcast_addr.sin_family = AF_INET;                /*設(shè)置協(xié)議族類行為AF*/mcast_addr.sin_addr.s_addr = inet_addr(MCAST_ADDR);/*設(shè)置多播IP地址*/mcast_addr.sin_port = htons(MCAST_PORT);        /*設(shè)置多播端口*/memset(buf,0,sizeof(buf));buf[0]='a';buf[1]='a';buf[2]='a';buf[3]='a';for(i=4;i<sizeof(buf)-5;i++){buf[i]='0';}buf[sizeof(buf)-5]='z';buf[sizeof(buf)-4]='z';buf[sizeof(buf)-3]='z';buf[sizeof(buf)-2]='z';buf[sizeof(buf)-1]=0x00;int count = 3000;                                          /*向多播地址發(fā)送數(shù)據(jù)*///while(count>0) {while(1) {int n = sendto(s,                           /*套接字描述符*/buf,     /*數(shù)據(jù)*/sizeof(buf),    /*長度*/0,(struct sockaddr*)&mcast_addr,sizeof(mcast_addr)) ;printf('sendto n=%d\n',n);if( n < 0){perror('sendto()');return -2;}printf('sendto n=%d\n',n);//count --;   usleep(1000);                          /*等待一段時間*/}return 0;}

net_rate.c

  1. #include <stdio.h>
  2. #include <malloc.h>
  3. #include <memory.h>
  4. #include <errno.h>
  5. #include <sys/stat.h>
  6. #include <sys/statfs.h>
  7. #include <dirent.h>
  8. #include <unistd.h>
  9. #include <string.h>
  10. #include <fcntl.h>
  11. #include <sys/types.h>
  12. #define DTV_CONFIG_ETH0_NET_INTERFACE 'eno1'
  13. #define DTV_CONFIG_LO_NET_INTERFACE 'lo'
  14. #define SERVICE_NET_DEFAULT_GET_NET_RATE_SECOND (5)
  15. typedef int caoft_bool;
  16. #ifndef NULL
  17. #define NULL 0L
  18. #endif
  19. #ifndef true
  20. #define true 1
  21. #endif
  22. #ifndef false
  23. #define false 0
  24. #endif
  25. typedef char caoft_s8;
  26. typedef unsigned char caoft_u8;
  27. typedef signed short caoft_s16;
  28. typedef unsigned short caoft_u16;
  29. typedef signed int caoft_s32;
  30. typedef unsigned int caoft_u32;
  31. typedef long longcaoft_s64;
  32. typedef unsigned long long caoft_u64;
  33. typedef long unsigned intcaoft_size_t;
  34. #undef INVALID_HANDLE
  35. #define INVALID_HANDLE(0xFFFFFFFF)
  36. #undef INVALID_VALUE
  37. #define INVALID_VALUE(0xFFFFFFFF)
  38. typedef caoft_s32 caoft_time_t;
  39. #define caoft_UNUSED(x) ((x)=(x))
  40. typedef void * caoft_phandle;
  41. typedef caoft_u32 caoft_uhandle;
  42. typedef caoft_s32 caoft_shandle;
  43. typedef enum{
  44. caoft_SUCCESS = 0,/** success HI_3G_CARD_SUCCESS*/
  45. caoft_FAILURE,
  46. caoft_NOT_INITIALIZED,/**HI_3G_CARD_ERR_NOINIT error code for card not init */
  47. caoft_INVALID_PARAMETER,/**HI_3G_CARD_ERR_INVAL error code for invalid args */
  48. caoft_NOT_SUPPORT,/** HI_3G_CARD_ERR_ENOCARD error code for no support card when scan */
  49. }caoft_error_code_e;
  50. /*************************************************************************
  51. Description
  52. s級的sleep
  53. Definition
  54. void caoft_os_sleep(caoft_s32 s);
  55. Arguments
  56. s:秒數(shù)
  57. Return Value
  58. Comments
  59. See Also
  60. *************************************************************************/
  61. void caoft_os_sleep(caoft_u32 s)
  62. {
  63. sleep(s);
  64. }
  65. /*************************************************************************
  66. Description
  67. 文件打開操作
  68. Definition
  69. caoft_phandle caoft_fs_file_open(const caoft_s8* path,const caoft_s8 * mode);
  70. Arguments
  71. path:文件路徑
  72. mode:打開模式,如'r+'
  73. Return Value
  74. true:failure
  75. false:sucess
  76. Comments
  77. See Also
  78. *************************************************************************/
  79. caoft_phandle caoft_fs_file_open(const caoft_s8* path,const caoft_s8 * mode)
  80. {
  81. FILE *file=NULL;
  82. if((NULL==path)||(NULL == mode))
  83. {
  84. printf(' path mode NULL\n');
  85. return NULL;
  86. }
  87. file=fopen((const char *)path, (const char *)mode);
  88. if(NULL==file)
  89. {
  90. printf('fopen failed,path:[%s],mode=[%s]\t error: %s!\n', path, mode, strerror(errno));
  91. return NULL;
  92. }
  93. return (caoft_phandle)file;
  94. }
  95. /*************************************************************************
  96. Description
  97. 文件關(guān)閉操作
  98. Definition
  99. caoft_bool caoft_fs_file_close(caoft_phandle handle)
  100. Arguments
  101. handle:文件句柄
  102. Return Value
  103. true:failure
  104. false:sucess
  105. Comments
  106. See Also
  107. *************************************************************************/
  108. caoft_bool caoft_fs_file_close(caoft_phandle handle)
  109. {
  110. if(0==handle)
  111. {
  112. printf(' handle NULL\n');
  113. return true;
  114. }
  115. fclose((FILE *)handle);
  116. return false;
  117. }
  118. /*獲取網(wǎng)口上行下行網(wǎng)速*/
  119. static caoft_error_code_e service_net_get_current_flow(caoft_s8 *netname,caoft_u64 *rcv_flow,caoft_u64 *tx_flow)
  120. {
  121. FILE * net_dev_file;//文件指針
  122. caoft_s8 buffer[1024];//文件中的內(nèi)容暫存在字符緩沖區(qū)里
  123. caoft_s8 * match; //用以保存所匹配字符串及之后的內(nèi)容
  124. caoft_u32 counter = 0;//用以計算tx 發(fā)送字節(jié)數(shù)的位置
  125. caoft_u32 i = 0;
  126. caoft_s8 tmp_value[128];//偏移數(shù)據(jù)數(shù)值使用
  127. if((NULL == netname)||(NULL == rcv_flow)||(NULL == tx_flow))
  128. {
  129. printf('bad param\n');
  130. return caoft_INVALID_PARAMETER;
  131. }
  132. if ( (net_dev_file=caoft_fs_file_open('/proc/net/dev', 'r')) == NULL ) //打開文件/pro/net/dev/,我們要讀取的數(shù)據(jù)就是它啦
  133. {
  134. printf('caoft_fs_file_open /proc/net/dev/ failed!\n');
  135. return caoft_OPEN_FAILED;
  136. }
  137. memset(buffer,0,sizeof(buffer));
  138. while(fgets(buffer,sizeof(buffer),net_dev_file) != NULL)
  139. {
  140. match = strstr(buffer,netname);
  141. if(NULL == match)
  142. {
  143. //service_net_debug_info('no %s keyword to find!\n',netname);
  144. continue;
  145. }
  146. else
  147. {
  148. //service_net_debug_info('%s\n',buffer);
  149. match = match + strlen(netname) + strlen(':');/*地址偏移到冒號*/
  150. sscanf(match,'%llu ',rcv_flow);
  151. memset(tmp_value,0,sizeof(tmp_value));
  152. sscanf(match,'%s ',tmp_value);
  153. match = match + strlen(tmp_value);
  154. counter = 0;
  155. for(i=0;i<strlen(buffer);i++)
  156. {
  157. if(0x20 == *match)
  158. {
  159. match ++;
  160. }
  161. else
  162. {
  163. if(8 == counter)
  164. {
  165. sscanf(match,'%llu ',tx_flow);
  166. }
  167. memset(tmp_value,0,sizeof(tmp_value));
  168. sscanf(match,'%s ',tmp_value);
  169. match = match + strlen(tmp_value);
  170. counter ++;
  171. }
  172. }
  173. //service_net_debug_info('%s rcv_flow:%llu bytes tx_flow:%llu bytes\n',netname,*rcv_flow,*tx_flow);
  174. }
  175. caoft_fs_file_close(net_dev_file);
  176. return caoft_SUCCESS;/*返回成功*/
  177. }
  178. caoft_fs_file_close(net_dev_file);
  179. return caoft_FAILURE;
  180. }
  181. int main(void)
  182. {
  183. caoft_u64 last_eth0_rcv_flow = 0;
  184. caoft_u64 last_eth0_tx_flow = 0;
  185. caoft_u64 current_eth0_rcv_flow = 0;
  186. caoft_u64 current_eth0_tx_flow = 0;
  187. caoft_u64 last_lo_rcv_flow = 0;
  188. caoft_u64 last_lo_tx_flow = 0;
  189. caoft_u64 current_lo_tx_flow = 0;
  190. caoft_u64 current_lo_rcv_flow = 0;
  191. caoft_u32 eth0_tx_speed = 0;
  192. caoft_u32 eth0_rx_speed = 0;
  193. caoft_u32 lo_tx_speed = 0;
  194. caoft_u32 lo_rx_speed = 0;
  195. caoft_error_code_e ret = caoft_FAILURE;
  196. while(1)
  197. {
  198. ret = service_net_get_current_flow(DTV_CONFIG_ETH0_NET_INTERFACE,&last_eth0_rcv_flow,&last_eth0_tx_flow);
  199. if(caoft_SUCCESS != ret)
  200. {
  201. printf('service_net_get_current_flow failed %s ret=%d\n',DTV_CONFIG_ETH0_NET_INTERFACE,ret);
  202. caoft_os_sleep(SERVICE_NET_DEFAULT_GET_NET_RATE_SECOND);
  203. continue;
  204. }
  205. ret = service_net_get_current_flow(DTV_CONFIG_LO_NET_INTERFACE,&last_lo_rcv_flow,&last_lo_tx_flow);
  206. if(caoft_SUCCESS != ret)
  207. {
  208. printf('service_net_get_current_flow failed %s ret=%d\n',DTV_CONFIG_LO_NET_INTERFACE,ret);
  209. caoft_os_sleep(SERVICE_NET_DEFAULT_GET_NET_RATE_SECOND);
  210. continue;
  211. }
  212. caoft_os_sleep(SERVICE_NET_DEFAULT_GET_NET_RATE_SECOND);
  213. ret = service_net_get_current_flow(DTV_CONFIG_ETH0_NET_INTERFACE,&current_eth0_rcv_flow,&current_eth0_tx_flow);
  214. if(caoft_SUCCESS != ret)
  215. {
  216. printf('service_net_get_current_flow failed %s ret=%d\n',DTV_CONFIG_ETH0_NET_INTERFACE,ret);
  217. caoft_os_sleep(SERVICE_NET_DEFAULT_GET_NET_RATE_SECOND);
  218. continue;
  219. }
  220. ret = service_net_get_current_flow(DTV_CONFIG_LO_NET_INTERFACE,&current_lo_rcv_flow,&current_lo_tx_flow);
  221. if(caoft_SUCCESS != ret)
  222. {
  223. printf('service_net_get_current_flow failed %s ret=%d\n',DTV_CONFIG_LO_NET_INTERFACE,ret);
  224. caoft_os_sleep(SERVICE_NET_DEFAULT_GET_NET_RATE_SECOND);
  225. continue;
  226. }
  227. eth0_tx_speed = (((current_eth0_tx_flow - last_eth0_tx_flow)*8)/SERVICE_NET_DEFAULT_GET_NET_RATE_SECOND);/*與節(jié)目顯示約定,精確兩位小數(shù),所以與100相乘*/
  228. eth0_rx_speed = (((current_eth0_rcv_flow - last_eth0_rcv_flow)*8)/SERVICE_NET_DEFAULT_GET_NET_RATE_SECOND);/*與節(jié)目顯示約定,精確兩位小數(shù),所以與100相乘*/
  229. lo_tx_speed = (((current_lo_tx_flow - last_lo_tx_flow)*8)/SERVICE_NET_DEFAULT_GET_NET_RATE_SECOND);/*與節(jié)目顯示約定,精確兩位小數(shù),所以與100相乘*/
  230. lo_rx_speed = (((current_lo_rcv_flow - last_lo_rcv_flow)*8)/SERVICE_NET_DEFAULT_GET_NET_RATE_SECOND);/*與節(jié)目顯示約定,精確兩位小數(shù),所以與100相乘*/
  231. printf('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n');
  232. printf('eth0 tx=%d KBytes/s rx=%d KBytes/s\n',eth0_tx_speed/8/1024,eth0_rx_speed/8/1024);
  233. printf('lo tx=%d rx=%d\n',lo_tx_speed,lo_rx_speed);
  234. printf('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n');
  235. }
  236. return 0;
  237. }

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多