2012-02-11 75 views
6

是否可以從一個套接字上的多個多播組接收數據?訂閱一個套接字上的多個多播組(Linux,C)

例如:

void AddGroup(int sock, 
       const char* mc_addr_str, 
       int mc_port, 
       const char* interface) { 
    struct sockaddr_in mc_addr; 
    memset(&mc_addr, 0, sizeof(mc_addr)); 
    mc_addr.sin_family  = AF_INET; 
    mc_addr.sin_addr.s_addr = inet_addr(mc_addr_str); 
    mc_addr.sin_port  = htons(mc_port); 

    if ((bind(sock, (struct sockaddr *) &mc_addr, 
      sizeof(mc_addr))) < 0) { 
    perror("bind() failed"); 
    exit(1); 
    } 

    // construct an IGMP join request structure 
    struct ip_mreq mc_req; 
    mc_req.imr_multiaddr.s_addr = inet_addr(mc_addr_str); 
    mc_req.imr_interface.s_addr = inet_addr(interface); 

    if ((setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, 
        (void*) &mc_req, sizeof(mc_req))) < 0) { 
    perror("setsockopt() failed"); 
    exit(1); 
    } 
} 

此代碼的工作,當我添加一個多播羣組。但是當我嘗試添加另一個時,「綁定」失敗。我不太明白爲什麼綁定需要在那裏呢? (但是沒有它,代碼就無法工作)。

理想情況下,我想在同一套接字上多次調用AddGroup。這可能嗎?或者我需要每組一個套接字,然後只使用輪詢?

回答

3

您只綁定一次套接字。第二次跳過綁定,看看會發生什麼。

-3

我不認爲有可能在給定套接字上加入多個多播組。套接字由源IP /端口和目的地IP /端口的配對定義。操作系統不知道如何處理來自第二個ip /端口的數據,因爲它沒有套接字發送給它。

綁定對於註冊與操作系統的連接是必需的。基本上就像註冊一個文件句柄。

做到這一點的最佳方法是爲每個多播組創建一個套接字,然後調用select()。如果任何套接字有數據準備好讀取,select()會通知您。

檢查您的手冊頁以獲取有關socket(),bind()和select()的更多信息。

+2

你是不正確的護理。你可以加入儘可能多的小組,只要你喜歡。加入多播組與識別元組無關。 – EJP 2012-02-13 09:18:49

6

根據需要,您可以使用適當的setsockopt()調用(IP_ADD_MEMBERSHIP選項)而不是bind()來加入儘可能多的多播組。

+0

當我在AddGroup的後續調用中刪除「綁定」時,只有第一個組播組似乎被「訂閱」到。 – Switch 2012-02-14 00:53:30

+0

@交換如果通過默認IP路由無法訪問組,您需要在加入組時指定適當的出局本地地址,因此「添加成員資格」IGMP消息會沿相應的方向行進。 – EJP 2012-08-03 01:05:08

2

bind爲被動地址,即對於IPv4爲0.0.0.0,並且使用ASM或SSM來引入附加的組,例如, IP_ADD_MEMBERSHIP列出。

您只能使用bind一次。

2

您可以在單個套接字上加入想要的多個組播組。請參閱setsockopt(),IP_PKTINFO以瞭解如何識別您正在從中讀取數據的多播組。

0

是的,這是可能的:看在示例中的鏈接(http://www.tenouk.com/Module41c.html) 要在幾個步驟縮短這件事:

  1. 您與SO_REUSEADDR setsockopt的
  2. 您綁定的INADDR_ANY
  3. 你使用IP_ADD_MEMBERSHIP的setsockopt在要接收數據報的每個組上。
  4. 在我看來,使用IP_PKTINFO給出了一個選項,以區分接收的數據包,但發送者必須採取有關準備它們(Setting the source IP for a UDP socket