2014-03-13 40 views
0

一週左右,我一直在研究從單一來源向多個客戶端發送數據報的方法,並發現IP支持在範圍224.0.0.0234.255.255.255之間進行多播。我已經閱讀了一些描述該技術的文檔,但沒有找到任何幫助我理解如何使用它們的文檔。使用多播地址和組

從我收集的內容看,程序似乎要求OS內核加入一個非關聯的多播組,然後開始通過UDP將套接字通過UDP發送到多播地址。其他的一切都是通過廣域網處理的,而不需要在發送地址的任何物理內容。

這條思路一直受到我讀過的內容的支持,但還沒有得到證實。這個想法是否正確?如果有問題,有什麼錯誤?

回答

1

這實質上是正確的。

在接收端,首先打開一個偵聽特定端口的套接字。然後您加入給定網絡接口上的多播地址。這樣做會導致操作系統向網絡發送IGMP消息,通知正在加入組的路由器。

在發送方,您打開一個套接字,然後配置多播的傳出網絡接口。一旦你這樣做,你可以發送數據包到任何多播地址。

下面是一個例子發件人在C:

#include <sys/types.h> 
#include <sys/socket.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <netinet/in.h> 
#include <strings.h> 
#include <arpa/inet.h> 

int main(int argc, char *argv[]) 
{ 
    struct sockaddr_in sin; 
    struct in_addr out_addr; 
    char mes[255], ttl; 
    int sock; 

    printf("Enter message: "); 
    fgets(mes, sizeof(mes), stdin); 
    bzero(&sin,sizeof(sin)); 
    sin.sin_family=AF_INET; 
    sin.sin_addr.s_addr=inet_addr(argv[1]); 
    sin.sin_port=htons(atoi(argv[2])); 
    if ((sock=socket(AF_INET,SOCK_DGRAM,0))==-1) { 
    perror("Error creating socket"); 
    exit(1); 
    } 
    out_addr.s_addr=inet_addr(argv[3]); 
    if (setsockopt(sock,IPPROTO_IP,IP_MULTICAST_IF,(char *)&out_addr,sizeof(out_addr))== -1) { 
    perror("Error setting outgoing interface"); 
    close(sock); 
    exit(1); 
    } 
    if (sendto(sock,mes,strlen(mes),0,(struct sockaddr *)&sin,sizeof(sin))==-1) { 
    close(sock); 
    perror("Send error"); 
    } 
    close(sock); 
} 

這裏是一個樣本接收器在C:

#include <stdio.h> 
#include <stdlib.h> 
#include <strings.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 

int main(int argc, char *argv[]) 
{ 
    int addr_len; 
    struct sockaddr_in sin,sin_recv; 
    struct ip_mreq multi; 
    char mes[255]; 
    int sock; 

    bzero(&sin,sizeof(sin)); 
    multi.imr_multiaddr.s_addr=inet_addr(argv[1]); 
    multi.imr_interface.s_addr=inet_addr(argv[2]); 
    sin.sin_family = AF_INET; 
    sin.sin_addr.s_addr = INADDR_ANY; 
    sin.sin_port = htons(atoi(argv[3])); 
    if ((sock=socket(AF_INET,SOCK_DGRAM,0))==-1) { 
    perror("Error creating socket"); 
    exit(1); 
    } 
    if (setsockopt(sock,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char *)&multi,sizeof(multi))== -1) { 
    perror("Error joining multicast group"); 
    close(sock); 
    exit(1); 
    } 
    if (bind(sock,(struct sockaddr *)&sin,sizeof(sin))==-1) { 
    perror("Error binding socket"); 
    close(sock); 
    exit(1); 
    } 
    while (1) { 
    bzero(mes,sizeof(mes)); 
    bzero(&sin_recv,sizeof(sin_recv)); 
    addr_len=sizeof(sin_recv); 
    printf("Waiting for packet...\n"); 
    if (recvfrom(sock,mes,sizeof(mes),0,(struct sockaddr *)&sin_recv,&addr_len)==-1) { 
     perror("error recving socket"); 
     close(sock); 
     exit(1); 
    } 
    printf("Got packet\n"); 
    printf("Origin: %s port %d\n",inet_ntoa(sin_recv.sin_addr),sin_recv.sin_port); 
    printf("Message: %s\n",mes); 
    } 
} 
+0

感謝您對這個問題的確認和澄清。我擔心的是,很少有人對這個網絡場所感興趣,而這個問題不會得到回答。 –

+0

[這是一個很好的例子]和一個很好的編輯答案(http://cboard.cprogramming.com/networking-device-communication/144188-issue-multicast-when-socket-isn't-bound-inaddr_any.html)。 – Auzias