隨著全球互連網(Internet)的迅猛發展,上網人數正以幾何級數快速增長,以網際網路技術為主導的資料通訊在通訊業務總量中的比列迅速上升,網際網路業務已成為多媒體通訊業中發展最為迅速、競爭最為激烈的領域。Internet網路傳輸和處理能力的大幅提高,使得網上應用業務越來越多,特別是視音頻壓縮技術的發展和成熟,使得網上視音頻業務成為Internet網上最重要的業務之一。
在Internet上實現的ApsaraVideo for VOD(VOD)、可視電話、視頻會議等視音頻業務和一般業務相比,有著資料量大、時延敏感性強、期間長等特點。因此採用最少時間、最小空間來傳輸和解決視音頻業務所要求的網路利用率高、傳輸速度快、即時性強的問題,就要採用不同於傳統單播、廣播機制的轉寄技術及QoS服務保證機制來實現,而IP多播技術是解決這些問題的關鍵技術。
一、IP多播技術的概念
IP多播(也稱多址廣播或組播)技術,是一種允許一台或多台主機(多播源)發送單一資料包到多台主機(一次的,同時的)的TCP/IP網路技術。多播作為一點對多點的通訊,是節省網路頻寬的有效方法之一。在網路音頻/視頻廣播的應用中,當需要將一個節點的訊號傳送到多個節點時,無論是採用重複點對點通訊方式,還是採用廣播方式,都會嚴重浪費網路頻寬,只有多播才是最好的選擇。多播能使一個或多個多播源只把資料包發送給特定的多播組,而只有加入該多播組的主機才能接收到資料包。目前,IP多播技術被廣泛應用在網路音頻/視頻廣播、AOD/VOD、網路視頻會議、多媒體遠程教育、“push”技術(如股票行情等)和虛擬現實遊戲等方面。
二、IP多播技術的基礎知識
1. IP多播地址和多播組
IP多播通訊必須依賴於IP多播地址,在IPv4中它是一個D類IP地址,範圍從224.0.0.0到239.255.255.255,並被劃分為局部連結多播地址、預留多播地址和系統管理權限多播地址三類。其中,局部連結多播位址範圍在224.0.0.0~224.0.0.255,這是為路由協議和其它用途保留的地址,路由器並不轉寄屬於此範圍的IP包;預留多播地址為224.0.1.0~238.255.255.255,可用於全球範圍(如Internet)或網路通訊協定;系統管理權限多播地址為239.0.0.0~239.255.255.255,可供組織內部使用,類似於私人IP地址,不能用於Internet,可限制多播範圍。
使用同一個IP多播地址接收多播資料包的所有主機構成了一個主機群組,也稱為多播組。一個多播組的成員是隨時變動的,一台主機可以隨時加入或離開多播組,多播群組成員的數目和所在的地理位置也不受限制,一台主機也可以屬於幾個多播組。此外,不屬於某一個多播組的主機也可以向該多播組發送資料包。
2.多播分布樹
為了向所有接收主機傳送多播資料,用多播分布樹來描述IP多播在網路中傳輸的路徑。多播分布樹有兩個基本類型:有源樹和共用樹。
有源樹是以多播源作為有源樹的根,有源樹的分支形成通過網路到達接收主機的分布樹,因為有源樹以最短的路徑貫穿網路,所以也常稱為最短路徑樹(SPT)。共用樹以多播網中某些可選擇的多播路由中的一個作為共用樹的公用根,這個根被稱為匯合點(RP)。共用樹又可分為單向共用樹和雙向共用樹。單向共用樹指多播資料流必須經過共用樹從根發送到多播接收機。雙向共用樹指多播資料流可以不經過共用樹。
3.逆向路徑轉寄
逆向路徑轉寄(RPF)是多播路由協議中多播資料轉寄過程的基礎,其工作機制是當多播資訊通過有源樹時,多播路由器檢查到達的多播資料包的多播源地址,以確定該多播資料包所經過的介面是否在有源的分支上,如果在,則RPF檢查成功,多播資料包被轉寄;如果RPF檢查失敗,則丟棄該多播資料包。
4.Internet多播主幹(MBONE)網路
Internet多播主幹(MBONE)網路是由一系列相互串連的子網主機和相互串連支援IP多播的路由器組成。它可以看成是一個架構在Internet物理網路上層的虛擬網,在該虛擬網中,多播源發出的多播資訊流可直接在支援IP多播的路由器組之間傳輸,而在多播路由器組和非多播路由器組之間要通過點對點隧道技術進行傳輸。
三、IP多播路由及其協議
1. IP多播路由的基本類型
多播路由的一種常見的思路就是在多播群組成員之間構造一棵擴充分布樹。在一個特定的“發送源,目的組”對上的IP多播流量都是通過這個擴充樹從發送源傳輸到接受者的,這個擴充樹串連了該多播組中所有主機。不同的IP多播路由協議使用不同的技術來構造這些多播擴充樹,一旦這個樹構造完成,所有的多播流量都將通過它來傳播。
根據網路中多播群組成員的分布,總的說來IP多播路由協議可以分為以下兩種基本類型。第一種假設多播群組成員密集地分布在網路中,也就是說,網路大多數的子網都至少包含一個多播群組成員,而且網路頻寬足夠大,這種被稱作“密集模式”(Dense-Mode)的多播路由協議依賴於廣播技術來將資料“推”向網路中所有的路由器。密集模式路由協議包括距離向量多播路由協議(DVMRP:Distance Vector Multicast Routing Protocol)、多播先開啟最短的路徑協議(MOSPF:Multicast Open Shortest Path First)和密集模式獨立多播協議(PIM-DM:Protocol-Independent Multicast-Dense Mode)等。
多播路由的第二種類型則假設多播群組成員在網路中是稀疏分散的,並且網路不能提供足夠的傳輸頻寬,比如Internet上通過ISDN線路串連分散在許多不同地區的大量使用者。在這種情況下,廣播就會浪費許多不必要的網路頻寬從而可能導致嚴重的網路效能問題。於是稀疏模式多播路由協議必須依賴於具有路由選擇能力的技術來建立和維持多播樹。稀疏模式主要有基於核心樹的多播協議(CBT:Core Based Tree)和稀疏模式獨立協議多播(PIM-SM:Protocol-Independent Multicast-Sparse Mode)。
2.密集模式協議
(1)距離向量多播路由協議 (DVMRP)
第一個支援多播功能的路由協議就是距離向量多播路由協議。它已經被廣泛地應用在多播骨幹網MBONE上。
DVMRP為每個發送源和目的主機群組構建不同的分布樹。每個分布樹都是一個以多播發送源作為根,以多播接受目的主機作為葉的最小擴充分布樹。這個分布樹為發送源和組中每個多播接受者之間提供了一個最短路徑,這個以“跳數”為單位的最短路徑就是DVMRP的量度。當一個發送源要向多播組中發送訊息時,一個擴充分布樹就根據這個請求而建立,並且使用“廣播和修剪”的技術來維持這個擴充分布樹。
擴充分布樹構建過程中的選擇性發送多播包的具體運作是:當一個路由器接收到一個多播包,它先檢查它的單播路由表來尋找到多播組發送源的最短路徑的介面,如果這個介面就是這個多播包到達的介面,那麼路由器就將這個多播組資訊記錄到它的內部路由表(指明該組資料包應該發送的介面),並且將這個多播包向除了接受到該資料包的路由器以外的其他臨近路由器繼續發送。如果這個多播包的到達介面不是該路由器到發送源的最短路徑的介面,那麼這個包就被丟棄。這種機制被稱為“反向路徑廣播”(Reverse-Path Broadcasting)機制,保證了構建的樹中不會出現環,而且從發送源到所有接受者都是最短路徑。
對子網中密集分布的多播組來說DVMRP能夠很好的運作,但是對於在範圍比較大的地區上分散分布的多播組來說,周期性的廣播行為會導致嚴重的效能問題。DVMRP不能支援大型網路中稀疏分散的多播組。
(2)多播先開啟最短的路徑 (MOSPF)
先開啟最短的路徑(OSPF)是一個單播路由協議,它將資料包在最小開銷路徑上進行路由傳送,這裡的開銷是表示鏈路狀態的一種量度。除了路徑中的跳數以外,其他能夠影響路徑開銷的網路績效參數還有Server Load Balancer資訊、應用程式需要的QoS等。
MOSPF是為單播路由多播使用設計的。MOSPF依賴於OSPF作為單播路由協議,就象DVMRP也包含它自己的單播協議一樣。在一個OSPF/MOSPF網路中每個路由器都維持一個最新的全網路拓撲結構圖。這個“鏈路狀態”資訊被用來構建多播分布樹。
每個MOSPF路由器都通過IGMP協議周期性的收集多播群組成員關係資訊。這些資訊和這些鏈路狀態資訊被發送到其路由網域中的所有其他路由器。路由器將根據它們從臨近路由器接收到的這些資訊更新他們的內部串連狀態資訊。由於每個路由器都清楚整個網路的拓撲結構,就能夠獨立的計算出一個最小開銷擴充樹,將多播發送源和多播群組成員分別作為樹的根和葉。這個樹就是用來將多播流從發送源發送到多播群組成員的路徑。
(3)獨立多播密集模式協議(PIM-DM)
獨立多播協議(PIM)是一種標準的多播路由協議,並能夠在Internet上提供可擴充的域間多播路由而不依賴於任何單播協議。PIM有兩種運行模式,一種是密集分布多播組模式,另一個是稀疏分布多播組模式,前者被稱為獨立多播密集模式協議(PIM-DM),後者被稱為獨立多播稀疏模式協議(PIM-SM)。
PIM-DM有點類似於DVMRP,這兩個協議都使用了反向路徑多播機制來構建分布樹。它們之間的主要不同在於PIM完全不依賴於網路中的單播路由協議而DVMRP依賴於某個相關的單播路由協議機制,並且PIM-DM比DVMRP簡單。
PIM-DM協議和所有的密集模式路由協議一樣也是資料驅動的。但是既然PIM-DM不依賴於任何單播路由協議,路由器某個接收埠(就是返回到源的最短路徑的連接埠)接收到的多播資料包被發送到所有下行介面直到不需要的分枝從樹中被修剪掉。DVMRP在樹構建階段能夠使用單播協議提供的拓撲資料有選擇性的向下行發送資料包,PIM-DM則更加傾向於簡單性和獨立性,甚至不惜增加資料包複製引起的額外開銷。
2.稀疏模式多播路由協議
當多播組在網路中集中分布或者網路提供足夠大頻寬的情況下,密集模式多播路由協議是一個有效方法,當多播群組成員在廣泛地區內稀疏分布時,就需要另一種方法即稀疏模式多播路由協議將多播流量控制在串連到多播群組成員的鏈路路徑上,而不會“泄漏”到不相關的鏈路路徑上,這樣既保證了資料轉送的安全,又能夠有效控制網路中的總流量和路由器的負載。
(1)基於核心樹的多播協議 (CBT)
和DVMRP和MOSPF為每個“發送源、目的組”對構建最短路徑樹不同的是,CBT協議只構建一個樹給組中所有成員共用,這個樹也就被稱為共用樹。整個多播組的多播通訊量都在這個共用樹上進行收發而不論發送源有多少或者在什麼位置。這種共用樹的使用能夠極大的減少路由器中的多播狀態資訊。
CBT共用樹有一個核心路由器用來構建這個樹。要加入的路由器發送加入請求給這個核心路由器。核心路由器接收到加入請求後,沿反路徑返回一個確認,這樣就構成了樹的一個分枝。加入請求資料包在被確認之前不需要一直被傳送到核心路由器。如果加入請求包在到達核心路由器之前先到達樹上的某個路由器,該路由器就接收下這個請求包而不繼續向前發送並確認這個請求包。發送請求的路由器就串連到共用樹上了。 CBT將多播流量集中在最少數量的鏈路而不是在一個基於發送源的共用樹上。集中在核心路由器上的流量可能會引起多播路由的某些問題。某些版本的CBT支援多個多播核心的使用,和單個多播核心相比多核心更能達到Server Load Balancer。
(2)獨立多播稀疏模式協議 (PIM-SM)
和CBT相似,PIM-SM被設計成將多播限制在需要收發的路由器上。PIM-SM圍繞一個被稱為集中點(RP:Rendezvous Point)的路由器構建多播分布樹。這個集中點扮演著和CBT核心路由器相同的角色,接收者在集中點能尋找到新的發送源。但是PIM-SM比CBT更靈活,CBT的樹通常是多播組共用樹,PIM-SM中的獨立的接收者可以選擇是構建組共用樹還是最短路徑樹。
PIM-SM協議最初先為多播組構建一個組共用樹。這個樹由串連到集中點的寄件者和接收者共同構建,就像CBT協議圍繞著核心路由器構建的共用樹一樣。這共用樹建立以後,一個接受者(實際上是最接近這個接收者的路由器)可以選擇通過最短路徑樹改變到發送源的串連。這個操作的過程是通過向發送源發送一個PIM加入請求完成的。一旦從發送源到接收者的最短路徑建立了,通過RP的外部分枝就被修剪掉了。
四、IP多播應用的編程方法
在實際應用中,編程人員通常需要自己編製底層網路應用程式來實現網上的底層通訊,如具體實現IP多播通訊的功能。編製底層網路應用程式通常要藉助於網路資料通訊編程介面,而在不同的作業系統中所提供的網路編程介面是有所不同的,如在Microsoft Windows環境下的網路編程介面就是Windows通訊端(Windows Socket,簡稱Winsock)。
Winsock提供了包括TCP/IP、IPX等多種通訊協定下的編程介面。不同的Windows版本支援不同的Winsock版本,其中Windows 95等早期版本本身只支援Winsock1.1(16位)下的編程(可以通過安裝相關的軟體包使其支援Winsock2.0),而Windows98、Windows NT4.0、Windows 2000則直接支援Winsock2.0(32位)。Winsock2.0是Winsock1.1的擴充,除相容Winsock1.1 API外,還定義了一套可支援IP多播的與協議無關的API。
使用Winsock 2.0實現IP多播的一般步驟如下:
1.初始化Winsock資源
在使用Winsock之前,必須調用WSAStartup()函數初始化Windows Sockets DLL。它允許應用程式或DLL指定Windows Sockets API要求的版本。
2.建立通訊端
調用WSASocket()函數可以建立一個使用UDP協議的通訊端,它是加入多播組的初始化通訊端,並且以後資料的發送和接收都在該通訊端上進行。針對IP多播通訊,可將參數dwFlags設定為WSA_FLAG_MULTIPOINT_C_LEAF、WSA_FLAG_MULTIPOINT_D_LEAF和WSA_FLAG_OVERLAPPED的位和,指明IP多播通訊在控制層面和資料層面都是“無根的”,只存在分葉節點,它們可以任意加入一個多播組,而且從一個分葉節點發送的資料會傳送到每一個分葉節點(包括它自己);建立的通訊端具有重疊屬性。
3.設定通訊端的選項
調用setsockopt()函數為通訊端設定SO_REUSEADDR選項,以允許通訊端綁紮到一個已在使用的地址上。
4.綁定通訊端
調用bind()函數綁定通訊端,從而將建立好的通訊端與本地地址和本地連接埠聯絡起來。對於多播通訊來說,發送和接收資料通常採用同一個連接埠。
5.設定多播通訊端的模式
WSAIoctl()函數的命令碼SIO_MULTICAST_LOOP用來允許或禁止多播通訊時發送出去的通訊流量是否也能夠在同一個通訊端上被接收(即多播返回)。值得注意的是,在Windows 95/98/NT 4中,預設是允許多播返回,但不能設定禁止,否則會出錯;只有在Windows 2000以上版本中,才能設定允許/禁止多播返回。
WSAIoctl()函數的命令碼SIO_MULTICAST_SCOPE用來設定多播傳播的範圍,即存留時間TTL。每當多播路由器轉寄多播資料包時,資料包中的TTL值都會被減1,若資料包的TTL減少到0,則路由器將拋棄該資料包。TTL的值是多少,多播資料便最多能經過多少個多播路由器。例如,TTL值為0,則多播只能在本地主機的多個通訊端間傳播,而不能傳播到“網線”上;TTL值為1(預設值),則多播資料遇到第一個路由器,便會被它“無情”地丟棄,不允許傳出本網之外,即只有同一個網路內的多播群組成員才能收到多播資料。
6.加入一個多播組
調用WSAJoinLeaf()函數可加入一個多播組並指定角色(寄件者/接收者)。調用時,參數dwFlags可指定通訊端作為寄件者(JL_SENDER_ONLY)、接收者(JL_RECEIVER_ONLY)或身兼兩者(JL_BOTH)。調用成功後會返回一個多播通訊端,調用closesocket()函數關閉該通訊端就離開了多播組,此時可以調用WSAJoinLeaf()函數再次加入多播組。注意,對多播組資料的接收和發送不能在該通訊端上完成。
7.向多播組發送資料
調用sendto()函數,可在指定的UDP通訊端上向指定的多播組發送多播資料。調用時,參數to應指向多播組的IP地址。值得注意的是,若一個應用程式只是打算給多播組發送資料,便不必加入一個多播組。
8.等待事件
調用WSAAsyncSelect()函數,使通訊端置於非阻塞模式,這時應用程式就可在該通訊端上接收以Windows訊息為基礎的網路事件通知。例如,若參數lEvent值為FD_READ,則應用程式可在通訊端上接收到“資料正等待被讀入”的通知。
9.從多播組接收資料
調用recvfrom函數,可在指定的UDP通訊端上讀取輸入資料。多播通訊中資料的發送與接收一般採用同一個連接埠,因此其發送通訊端和接收通訊端是一樣的。
10.關閉通訊端,釋放Winsock資源。
在多播通訊結束後,先調用closesocket()函數關閉多播通訊端和UDP通訊端,然後調用WSACleanup()函數結束對Windows Sockets DLL的使用。
五、應用執行個體
為了說明IP多播技術的應用方法,本人在Visual C++.NET環境下設計了一個簡單的基於Windows Socket 2的IP多播應用程式,通過該例子讀者可以掌握IP多播應用程式設計的一般方法。該程式的具體設計方法如下:
1.在Visual Studio.NET中建立一個基於對話方塊的MFC項目CMulticastSocket。注意在“進階功能”設定中不要選擇“Windows通訊端”,這是因為MFC只支援Windows Socket 1而不支援Windows Socket 2。為了能使用Winsock 2 API編程,在程式中應包含“winsock2.h”標頭檔,並在項目中加入ws2_32.lib的靜態庫,該靜態庫應設定在項目屬性的“連結器”\“輸入”\“附加依賴項”中。
2.在對話方塊(類名CCMulticastSocketDlg)資源中,設定它的Caption為“WinSock 2多播應用程式”,並添加以下控制項:
靜態文本:Caption為“接收到的資訊:”;
編輯框:ID為IDC_RECEIVE_EDIT,Read Only、Auto Vscroll、Vertical Scroll和Multiline屬性值都為True
靜態文本:Caption為“發送的資訊:”
編輯框:ID為IDC_SEND_EDIT
第一個按鈕:Caption為“加入多播組(&J)”,ID為IDC_JOIN_BUTTON
第二個按鈕:Caption為“多播發送(&S)”,ID為IDC_SEND_BUTTON
第三個按鈕:Caption為“離開多播組(&L)”,ID為IDC_LEAVE_BUTTON
第四個按鈕:Caption為“退出(&Q)”,ID為IDC_QUIT_BUTTON
為兩個編輯框分別添加相關聯的CString類型的變數m_SendMessage和m_ReceiveMessage;為四個按鈕添加相應的訊息處理函數;為對話方塊添加定時器訊息(用於定時顯示接收到的訊息)及其訊息處理函數。
3.添加一個新的對話方塊資源,設定它的Caption為“加入多播組”,保留預設的兩個按鈕控制項,同時添加添加以下控制項:
靜態文本:Caption為“IP多播組地址:”
編輯框:ID為IDC_IPADDRESS_EDIT
靜態文本:Caption為“IP多播連接埠:”
編輯框:ID為IDC_PORT_EDIT
靜態文本:Caption為“存留時間:”
編輯框:ID為IDC_TTL_EDIT
複選框:Caption為“多播返回:”,ID為IDC_LOOPBACK_CHECK,Left Text屬性值為True。
為該對話方塊添加新的類CJoinGroupDlg,它的基類為CDialog,然後為該對話方塊中的三個編輯框分別添加相
關聯的變數,即CSting m_IPAddress、UINT m_nPort、UINT m_nTTL;為複選框添加相關聯的BOOL類型的變數m_Loopback。
4.在CMulticastSocketDlg.h檔案的前面添加CJoinGroupDlg的標頭檔:#include “JoinGroupDlg.h”,並在CCMulticastSocketDlg類中添加了一個CJoinGroupDlg類執行個體對象m_JoinDlg。
5.為了能在對話方塊中接收網路事件通知,應增加一個使用者自訂的訊息及訊息處理函數,具體實現方法如下:在CMulticastSocketDlg.h檔案的前面自訂訊息:#define WM_SOCK_MSG(WM_USER+166),並在afx_msg塊中說明訊息處理函數:afx_msg LRESULT OnSocketMsg (WPARAM wParam,LPARAM lParam);在CMulticastSocketDlg.cpp檔案中的訊息映射塊中,使用ON_MESSAGE (WM_SOCK_MSG,OnSocketMsg)巨集指令將訊息映射到訊息處理函數中,並具體實現訊息處理函數:LRESULT CCMulticastSocketDlg:: OnSocketMsg(WPARAM wParam,LPARAM lParam){…}。
該程式的主要代碼可參見程式清單,相關函數的詳細說明可參看Microsoft MSDN協助系統。為了節省篇幅,程式中省略了部分自動產生的和用於錯誤處理的代碼。
程式清單:
// CMulticastSocketDlg.cpp : 實現檔案
#include "stdafx.h"
#include "winsock2.h"
#include "CMulticastSocket.h"
#include "CMulticastSocketDlg.h"
……
DWORD cbRet;
SOCKET Sock,SockM; file://UDP通訊端,多播通訊端
BOOL bFlag,bJoin;
SOCKADDR_IN local,Remote,From; file://分別指向本地、多播組和資料來源的IP地址與連接埠
int Fromlen;
char ReceiveBuf[32000]; file://接收緩衝區
BOOL bDataReceived;
……
BEGIN_MESSAGE_MAP(CCMulticastSocketDlg, CDialog)
……
ON_BN_CLICKED(IDC_JOIN_BUTTON, OnBnClickedJoinButton)
ON_BN_CLICKED(IDC_LEAVE_BUTTON, OnBnClickedLeaveButton)
ON_BN_CLICKED(IDC_QUIT_BUTTON, OnBnClickedQuitButton)
ON_BN_CLICKED(IDC_SEND_BUTTON, OnBnClickedSendButton)
ON_WM_TIMER()
ON_MESSAGE(WM_SOCK_MSG,OnSocketMsg)
END_MESSAGE_MAP()
BOOL CCMulticastSocketDlg::OnInitDialog()
{
CDialog::OnInitDialog();
……
SetTimer(1,100,NULL); file://設定定時器
Fromlen=sizeof(From);
bDataReceived=TRUE;
bJoin=FALSE;
return TRUE; // 除非設定了控制項的焦點,否則返回 TRUE
}
……
void CCMulticastSocketDlg::OnBnClickedJoinButton() file://加入多播組
{
if(m_JoinDlg.DoModal()==IDOK)
{
WORD wVersionRequested;
WSADATA wsaData;
int 北京中慶;
wVersionRequested = MAKEWORD(2,2);
北京中慶 = WSAStartup(wVersionRequested, &wsaData); file://初始化WinSock2資源
if(北京中慶!= 0){
AfxMessageBox("不能載入Windows通訊端動態連結程式庫,MB_OK");
return;
}
if (LOBYTE(wsaData.wVersion) !=2 || HIBYTE(wsaData.wVersion) !=2){
AfxMessageBox("WinSock DLL不支援2.0版本,MB_OK");
WSACleanup( );
return;
}
file://建立一個通訊端
Sock=WSASocket(AF_INET,SOCK_DGRAM,IPPROTO_UDP,
(LPWSAPROTOCOL_INFO)NULL,0,WSA_FLAG_OVERLAPPED
| WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF);
bFlag=TRUE; file://設定通訊端選項,使通訊端為可重用連接埠地址
setsockopt(Sock,SOL_SOCKET,SO_REUSEADDR,(char*)&bFlag,sizeof(bFlag));
file://將通訊端綁定到使用者指定連接埠及預設的介面
memset(&local,0,sizeof(local));
local.sin_family=AF_INET;
local.sin_port=htons((USHORT)m_JoinDlg.m_nPort);
local.sin_addr.s_addr=htonl(INADDR_ANY);
bind(Sock,(struct sockaddr FAR *)&local,sizeof(local));
file://設定多播資料報傳播範圍(存留時間TTL)
WSAIoctl(Sock,SIO_MULTICAST_SCOPE,&m_JoinDlg.m_nTTL,sizeof(int),
NULL,0,&cbRet,NULL,NULL);
file://設定多播返回(LOOKBACK)
BOOL nLoopBack=m_JoinDlg.m_Loopback;
WSAIoctl(Sock,SIO_MULTIPOINT_LOOPBACK,&nLoopBack,sizeof(nLoopBack),
NULL,0,&cbRet,NULL,NULL);
memset(&Remote,0,sizeof(Remote));
Remote.sin_family=AF_INET;
Remote.sin_addr.s_addr=inet_addr(m_JoinDlg.m_IPAddress);
Remote.sin_port=htons(m_JoinDlg.m_nPort);
file://加入到指定的多播組,並指定為既作為寄件者又作為接收者(JL_BOTH)
SockM=WSAJoinLeaf(Sock,(sockaddr*)&Remote,sizeof(Remote),
NULL,NULL,NULL,NULL,JL_BOTH);
WSAAsyncSelect(Sock,m_hWnd,WM_SOCK_MSG,FD_READ); file://註冊網路訊息及其網路事件
bJoin=TRUE;
}
}
void CCMulticastSocketDlg::OnBnClickedSendButton() file://多播發送
{
if(bJoin){
UpdateData(TRUE);
const char* strMessage=LPCTSTR(m_SendMessage);
int nSize=m_SendMessage.GetLength()+1;
sendto(Sock,strMessage,nSize,0,(sockaddr*)&Remote,sizeof(Remote));
}
else
AfxMessageBox("請先加入多播組!");
m_SendMessage="";
UpdateData(FALSE);
}
void CCMulticastSocketDlg::OnBnClickedLeaveButton()
{ file://離開多播組
closesocket(SockM);
closesocket(Sock);
WSACleanup();
m_SendMessage="";
m_ReceiveMessage="";
bDataReceived=TRUE;
bJoin=FALSE;
UpdateData(FALSE);
}
void CCMulticastSocketDlg::OnBnClickedQuitButton()
{ file://退出
DestroyWindow();
}
void CCMulticastSocketDlg::OnTimer(UINT nIDEvent) file://定時器處理函數,實現接收資訊的定時更新
{
if(bDataReceived)
{
m_ReceiveMessage+=ReceiveBuf;
m_ReceiveMessage+="\r\n";
bDataReceived=FALSE;
UpdateData(FALSE);
}
CDialog::OnTimer(nIDEvent);
}
LRESULT CCMulticastSocketDlg::OnSocketMsg(WPARAM wParam,LPARAM lParam)
{
file://檢索網路事件
switch(WSAGETSELECTEVENT(lParam)){
case FD_READ:
recvfrom(Sock,ReceiveBuf,32000,0,(sockaddr *)&From,&Fromlen);
bDataReceived=TRUE; file://設定已接收到一條資訊標誌
break;
}
return TRUE;
}
六、IP多播技術的應用
IP多播應用大致可以分為三類: 點對多點應用,多點對點應用和多點對多點應用。
1.點對多點應用
點對多點應用是指一個寄件者,多個接收者的應用形式,這是最常見的多播應用形式。典型的應用程式套件括:媒體廣播、媒體推送、資訊緩衝、事件通知和狀態監視。
媒體廣播:如演講、示範、會議等按議程進行的事件。其傳統媒體分發手段通常採用電視和廣播。這一類應用通常需要一個或多個恒定速率的資料流,當採用多個資料流(如語音和視頻)時,往往它們之間需要同步,並且相互之間有不同的優先順序。它們往往要求較高的頻寬、較小的延時抖動,但是對絕對延時的要求不是很高。
媒體推送:如新聞標題、天氣變化、運動比分等一些非商業關鍵性的動態變化的資訊。它們要求的頻寬較低、對延時也沒有什麼要求。
資訊緩衝:如網站資訊、執行代碼和其他基於檔案的分布式複製或緩衝更新。它們對頻寬的要求一般,對延時的要求也一般。
事件通知:如網路時間、組播會話議程、隨機數字、密鑰、配置更新、有效範圍的網路警報或其他有用資訊。它們對頻寬的需求有所不同,但是一般都比較低,對延時的要求也一般。
狀態監視:如股票價格、感測裝置、安全系統、生產資訊或其他即時資訊。這類頻寬要求根據採樣周期和精度有所不同,可能會有恒定速率頻寬或突髮帶寬要求,通常對頻寬和延時的要求一般。
2.多點對點的應用
多點對點應用是指多個寄件者,一個接收者的應用形式。通常是雙向請求響應應用,任何一端(多點或點)都有可能發起請求。典型應用程式套件括:資源尋找、資料收集、網路競拍、資訊詢問和Juke Box。
資源尋找:如服務定位,它要求的頻寬較低,對時延的要求一般。
資料收集: 它是點對多點應用中狀態監視應用的反向過程。它可能由多個感測裝置把資料發回給一個資料收集主機。頻寬要求根據採樣周期和精度有所不同,可能會有恒定速率頻寬或突髮帶寬要求,通常這類應用對頻寬和延時的要求一般。
網路競拍:拍賣者拍賣產品,而多個競拍者把標價發回給拍賣者。
資訊詢問:詢問者發送一個詢問,所有被詢問者返回應答。通常這對頻寬的要求較低,對延時不太敏感。
Juke Box:如支援準點播(Near-On-Demand)的音視頻倒放。通常接收者採用“帶外的”協議機制(如HTTP、RTSP、SMTP,也可以採用組播方式)發送倒放請求給一個調度隊列。它對頻寬的要求較高,對延時的要求一般。
3.多點對多點的應用
多點對多點應用是指多個寄件者和多個接收者的應用形式。通常,每個接收者可以接收多個寄件者發送的資料,同時,每個寄件者可以把資料發送給多個接收者。典型應用程式套件括:多點會議、資源同步、平行處理、協同處理、遠程學習、討論群組、分布式互動類比(DIS)、多人遊戲和Jam Session等。
多點會議: 通常音/視頻和文本應用構成多點會議應用。在多點會議中,不同的資料流擁有不同的優先順序。傳統的多點會議採用專門的多點控制單元來協調和分配它們,採用多播可以直接由任何一個寄件者向所有接收者發送,多點控制單元用來控制當前發言權。這類應用對頻寬和延時要求都比較高。
資源同步:如議程、目錄、資訊等分布資料庫的同步。它們對頻寬和延時的要求一般。
平行處理:如分布式平行處理。它對頻寬和延時的要求都比較高。
協同處理:如共用文檔的編輯。它對頻寬和延時的要求一般。
遠程學習:這實際上是媒體廣播應用加上對上行資料流(允許學生向老師提問)的支援。它對頻寬和延時的要求一般。
討論群組:類似於基於文本的多點會議,還可以提供一些類比的表達。
分布式互動類比(DIS):它對頻寬和時延的要求較高。
多人遊戲: 多人遊戲是一種帶討論群組能力的簡單分布式互動類比。它對頻寬和時延的要求都比較高。
Jam Session:這是一種音頻編碼共用應用。它對頻寬和時延的要求都比較高。
IP多播帶入了許多新的應用並減少了網路的擁塞和伺服器的負擔。目前IP多播的應用範圍還不夠大,但它能夠降低佔用頻寬,減輕伺服器負荷,並能改善傳送資料的品質,尤其適用於需要大量頻寬的多媒體應用,如音頻、視頻等。這項新技術已成為當前網路界的熱門話題,並將從根本上改變網路的體繫結構。