IGMP组播

多播是一种点对多点的通信方式,互联网中的D类地址用于组播: 224.0.0.0-239.255.255.255

多播地址分类

  1. 局部多播地址224.0.0.0-224.0.0.255 为路由协议和其它用途的保留地址
  2. 预留多播地址224.0.1.0-238.255.255.255 可用于全球范围
  3. 管理权限多播地址为 239.0.0.0~239.255.255.255,可供组织内部使用,类似于私有 IP 地址,不能用于 Internet,可限制多播范围。

 

A类地址(其中网络号为0,10,127位特殊地址)

 

| 第一字节 | 第二字节 | 第三字节 | 第四字节 |

| 0 | 网络号 |                           主机号            |

B类地址

| 第一字节 | 第二字节 | 第三字节 | 第四字节 |

| 0 | 1| 网络号 |          主机号                          |

C类地址

| 第一字节 | 第二字节 | 第三字节 | 第四字节 |

|0|1|0| 网络号 |                     主机号              |

 

组播基于无连接的udp协议实现数据发送和接收

创建socket

 int socket(int domain, int type, int protocol);
 domain设置成AF_INET,一般使用基于IP协议的UDP,TCP通信创建套接字都使用这个选项
 type设置成 SOCK_DGRAM  用户数据包协议

 

绑定本地IP地址到套接字

int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
const struct sockaddr *addr:    设置好的本机所有IP地址

 

设置组播属性,加入到组播:

setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
level:IPPROTO_IP
int optname:IP_ADD_MEMBERSHIP   //加入多播组
optval:设置好的多播结构体(多播IP:226.1.1.1)

接收数据

recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
int sockfd :句柄
struct sockaddr *src_addr 绑定的地址

 

使用多播技术加入

#include <stdio.h>
#include <netinet/in.h>   //for souockaddr_in
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <stdlib.h>

#include <arpa/inet.h>

//for select
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/select.h>

#include <strings.h>   //for bzero
#include <string.h>


char msg[1000];
int main(int argc,char **argv)
{

	int sockfd,nlen,ret,on=-1;
	int loop = 1;
	 struct sockaddr_in serveraddr;
	 struct ip_mreq  group;//多播结构体
    sockfd=socket(AF_INET, SOCK_DGRAM, 0);

	if(sockfd<0)
		{
		printf("sock err\n");
		return -1;
	}
	//setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST,&on, sizeof(on));

    serveraddr.sin_family= AF_INET;    //IPV4
    serveraddr.sin_port = htons(8888);
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);  
	nlen=sizeof(serveraddr);
	ret=bind(sockfd, (struct sockaddr *)&serveraddr,nlen);
    if(ret<0)
    	{
		printf("bind err\n");
		return -1;
	}

   ret = setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP,
                    &loop, sizeof(loop));
    if (ret < 0)
    {
       printf("setsockopt\n");
        return -1;
    }

	//设置多播结构体
    //设置多播组IP
	group.imr_multiaddr.s_addr = inet_addr("226.1.1.1");
	//将本机加入多播组
    group.imr_interface.s_addr =  INADDR_ANY;
	ret=setsockopt(sockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&group,sizeof(group));
	if(ret<0)
		{
			printf("Adding multicast group error\n");
			close(sockfd);
			return -1;
	}
	else printf("Adding multicast group...OK.\n");
	while(1)
		{
          memset(msg,0,1000);
		ret = recvfrom(sockfd, msg, sizeof(msg), 0,(struct sockaddr*)&serveraddr, &nlen);
				if( ret== -1)
				{
					perror("recvfrom()");
				}

			printf("msg:\n%s",msg);
				sleep(1);
	}
}

 

 

向创建好的"226.1.1.1"多播组发送消息:


#include <stdio.h>
#include <netinet/in.h>   //for souockaddr_in
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <stdlib.h>

#include <arpa/inet.h>

//for select
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/select.h>

#include <strings.h>   //for bzero
#include <string.h>


char msg[1000];

int main(int argc,char **argv)
{

	int sockfd,nlen,ret,on=1;
	 struct sockaddr_in local_addr;
	 struct ip_mreq group;
	 //socklen_t  length;
    sockfd=socket(AF_INET, SOCK_DGRAM, 0);
	if(sockfd<0)
		{
		printf("sock err\n");
		return -1;
	}
//	setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST,&on, sizeof(on));

    local_addr.sin_family= AF_INET;    //IPV4
    local_addr.sin_port = htons(8888);
    local_addr.sin_addr.s_addr = inet_addr("226.1.1.1");  //
	nlen=sizeof(local_addr);


	while(1)
		{
		if(fgets(msg,999,stdin))
			{
				ret=sendto(sockfd, msg, strlen(msg), 0,(struct sockaddr*)&local_addr, sizeof(local_addr));
				if(ret<0)
					{
					printf("send err");
					return -1;
				}
			}
	}
}

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值