15.1 多播

1. 多播,同时向多个主机传递数据

a. 多播服务器针对特定多播组,只发送一次数据;

b. 虽只发送一次数据,但是该组内的所有客户端都会接收数据;

c. 多播组数可以在IP地址范围内任意增加;

d. 加入特定组即可接收发送该多播组的数据。

多播是基于MBone这个虚拟网络工作的,它是以物理网络为基础,通过软件方法实现的多播通信必备虚拟网络。

多播组是D类IP地址,224.0.0.0-239.255.255.255

2. TTL time to live:用整数表示,每经过一个路由器减一,变零时销毁。

int send_sock;
int time_live = 64;
....
setsockopt(send_sock,IPPROTO_IP,IP_MULTICAST_TTL,(void *)&time_live,sizeof(time_live))
3. 加入多播组

struct ip_mreq join_adr;

join_adr.imr_multiaddr.s_addr = "多播组地址信息"
join_adr.imr_interface.s_addr = "加入多播组的主机地址信息"
setsockopt(recv_sock,IPPROTO_IP,IP_ADDR_MEMBERSHIP,(void *)&join_adr,sizeof(join_adr))

4. 示例,多播发送与接收

sender.c

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <unistd.h>  
#include <arpa/inet.h>  
#include <sys/socket.h>  
  
#define BUF_SIZE    30
#define TTL 64  
  
void error_handling(char *message);  
  
int main(int argc, char *argv[]){  
    int send_sock;
    FILE *fp;  
    char buf[BUF_SIZE];  
    struct sockaddr_in mul_adr;
    int time_live = TTL;  
      
    if(argc != 3){  
        printf("Usage : %s <group><port>\n",argv[0]);  
        exit(1);  
    }  

    send_sock = socket(PF_INET,SOCK_DGRAM,0);  
    if(send_sock == -1){  
        error_handling("socket() error");  
    }  
  
    memset(&mul_adr,0,sizeof(mul_adr));  
    mul_adr.sin_family=AF_INET;  
    mul_adr.sin_addr.s_addr=inet_addr(argv[1]);	//multi ip  
    mul_adr.sin_port=htons(atoi(argv[2]));  //port
  
    setsockopt(send_sock,IPPROTO_IP,IP_MULTICAST_TTL,(void *)&time_live,sizeof(time_live));
    if((fp = fopen("news.txt","r")) == NULL){
  	error_handling("fopen");
    }

    while(!feof(fp)){
	fgets(buf,BUF_SIZE,fp);
	sendto(send_sock,buf,strlen(buf),0,(struct sockaddr *)&mul_adr,sizeof(mul_adr));
	sleep(2);
    }
    fclose(fp);
    close(send_sock);

    return 0;  
}  
  
void error_handling(char *message){  
  
    fputs(message,stderr);  
    fputs("\n",stderr);  
    exit(1);  
}  
执行结果:

alex@alex-virtual-machine:/extra/tcpip$ ./sender 224.1.1.2 9190
alex@alex-virtual-machine:/extra/tcpip$

receiver.c

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <unistd.h>  
#include <arpa/inet.h>  
#include <sys/socket.h>  
  
#define BUF_SIZE    30
  
void error_handling(char *message);  
  
int main(int argc, char *argv[]){  
    int recv_sock;
    int str_len;
    char buf[BUF_SIZE];  
    struct sockaddr_in adr;
    struct ip_mreq join_adr;
      
    if(argc != 3){  
        printf("Usage : %s <group><port>\n",argv[0]);  
        exit(1);  
    }  

    recv_sock = socket(PF_INET,SOCK_DGRAM,0);  
    if(recv_sock == -1){  
        error_handling("socket() error");  
    }  
  
    memset(&adr,0,sizeof(adr));  
    adr.sin_family=AF_INET;  
    adr.sin_addr.s_addr=htonl(INADDR_ANY);	//multi ip  
    adr.sin_port=htons(atoi(argv[2]));  //port
  
    if(bind(recv_sock,(struct sockaddr *)&adr,sizeof(adr))==-1){
	error_handling("bind error");
    }

    join_adr.imr_multiaddr.s_addr = inet_addr(argv[1]);
    join_adr.imr_interface.s_addr = htonl(INADDR_ANY);

    setsockopt(recv_sock,IPPROTO_IP,IP_ADD_MEMBERSHIP,(void *)&join_adr,sizeof(join_adr));

    while(1){
    	str_len = recvfrom(recv_sock,buf,BUF_SIZE-1,0,NULL,0);
	if(str_len < 0){
	    break;
	}
	buf[str_len] = 0;
	fputs(buf,stdout);
    }
    close(recv_sock);

    return 0;  
}  
  
void error_handling(char *message){  
  
    fputs(message,stderr);  
    fputs("\n",stderr);  
    exit(1);  
}  
执行结果:

alex@alex-virtual-machine:/extra/tcpip$ ./recevier 224.1.1.2 9190
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netdb.h>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值