UDP組播接收端解析

2021-05-28 17:59:51 字數 2313 閱讀 6092

網路中的一台主機如果希望能夠接收到來自網路中其它主機發往某乙個組播組的資料報,那麼這麼主機必須先加入該組播組,然後就可以從組位址接收資料報。在廣域網中,還涉及到路由器支援組播路由等,但本文希望以乙個最為簡單的例子解釋清楚協議棧關於組播的乙個最為簡單明瞭的工作過程,甚至,我們不希望涉及到 igmp包。

我們先從乙個組播客戶端的應用程式入手來解析組播的工作過程:

#include

#include

#include

#include

#include "my_inet.h"

#include

#define maxbuf 256

#define puerto 5000

#define grupo "224.0.1.1"

int main(void)

if( (fd = socket( my_af_inet, sock_dgram, my_ipproto_udp) ) < 0 )

if( bind(fd, (struct sockaddr *)&srv, sizeof(srv)) < 0 )

if (inet_aton(grupo, &mreq.imr_multiaddr) < 0)

inet_aton( "172.16.48.2", &(mreq.imr_inte***ce) );

if( setsockopt(fd, sol_ip, ip_add_membership, &mreq,sizeof(mreq)) < 0 )

n = sizeof(cli);

while(1)else}}

這是乙個非常簡單的組播客戶端,它指定從組播組224.0.1.1的5000埠讀資料,並顯示在終端上,下面我們通過分析該程式來了解核心的工作過程。

前面我們講過,bind操作首先檢查使用者指定的埠是否可用,然後為socket的一些成員設定正確的值,並新增到雜湊表myudp_hash中。然後,協議棧每次收到udp資料,就會檢查該資料報的源和目的位址,還有源和目的埠,在myudp_hash中找到匹配的socket,把該資料報放入該 socket的接收佇列,以備使用者讀取。在這個程式中,bind操作把socket繫結到位址224.0.0.1:5000上, 該操作產生的直接結果就是,對於socket本身,下列值受影響:

struct inet_sock

這五個資料表示,該套接字在傳送資料報時,本地使用埠5000,本地可以使用任意乙個網路裝置介面,發往的目的位址不指定。在接收資料時,只接收發往ip位址224.0.0.1的埠為5000的資料。

程式中,緊接著bind有乙個setsockopt操作,它的作用是將socket加入乙個組播組,因為socket要接收組播位址224.0.0.1的資料,它就必須加入該組播組。結構體struct ip_mreq mreq是該操作的引數,下面是其定義:

struct ip_mreq ;

這個操作是在網路層上的乙個選項,所以級別是sol_ip,ip_add_membership選項把使用者傳入的引數拷貝成了struct ip_mreqn結構體:

struct ip_mreqn ;

多了乙個輸入介面的索引,暫時被拷貝成零。

該操作最終引發核心函式myip_mc_join_group執行加入組播組的操作。首先檢查imr_multiaddr是否為合法的組播位址,然後根據 imr_inte***ce的值找到對應的struct in_device結構。接下來就要為socket加入到組播組了,在inet_sock的結構體中有乙個成員mc_list,它是乙個結構體 struct ip_mc_socklist的鍊錶,每乙個節點代表socket當前正加入的乙個組播組,該鍊錶是有上限限制的,預設值為 ip_max_memberships(20),也就是說乙個socket最多允許同時加入20個組播組。下面是struct ip_mc_socklist的定義:

struct ip_mc_socklist

*/struct ip_sf_socklist   *sflist; };

struct ip_sf_socklist ;

除了multi成員,它還有乙個源過濾機制。如果我們新新增的struct ip_mreqn已經存在於這個鍊錶中(表示socket早就加入這個組播組了),那麼不做任何事情,否則,建立乙個新的struct ip_mc_socklist:

struct ip_mc_socklist ;

最後,呼叫myip_mc_inc_group函式在struct in_device和struct net_device的mc_list鍊錶中都添上相應的組播組節點,關於這部分的細節可以在前一篇文章《初識組播2》中找到。不再重複。

到此為止,我們完成了最為簡單的加入組播組的操作,對於同一子網內的情況,socket已經可以接收組播資料了,關於組播資料如何接收,下回分解。

UDP組播接收

網路中的一台主機如果希望能夠接收到來自網路中其它主機發往某乙個組播組的資料報,那麼這麼主機必須先加入該組播組,然後就可以從組位址接收資料報。在廣域網中,還涉及到路由器支援組播路由等,但本文希望以乙個最為簡單的例子解釋清楚協議棧關於組播的乙個最為簡單明瞭的工作過程,甚至,我們不希望涉及到 igmp包。...

udp組播示例 傳送 接收

原因不多說,目錄結構扁平,data.h如下 pragma once include include include define multicast ip 234.0.0.1 define multicast port 28928 pragma pack 1 typedef struct price...

udp組播測試

這周主要做了udp組播的測試 伺服器傳送端 include include include include include include include include include include include include include include std string hello...