组播编程

14 篇文章 0 订阅
4 篇文章 0 订阅

      单播用于两个主机之间的端对端通信。
      广播用于一个主机对整个局域网上所有主机上的数据通信。
      单播和广播是两个极端,要么对一个主机进行通信,要么对整个局域网上的主机进行通信。实际情况下,经常需要对一组特定的主机进行通信,而不是整个局域网上的所有主机,这就是组播的用途。
      组播,也称为“多播”,将局域网中同一业务类型主机进行了逻辑上的分组,进行数据收发的时候其数据仅仅在同一分组中进行,其他的主机没有加入此分组不能收发对应的数据

MAC地址:    

       MAC地址(英语:Media Access Control Address),直译为媒体访问控制地址,也称为局域网地址(LAN Address),以太网地址(Ethernet Address)或物理地址(Physical Address),它是一个用来确认网络设备位置的地址。在OSI模型中,第三层网络层负责IP地址,第二层数据链接层则负责MAC地址。MAC地址用于在网络中唯一标示一个网卡,一台设备若有一或多个网卡,则每个网卡都需要并会有一个唯一的MAC地址。
格式:
        MAC地址共48位(6个字节),以十六进制表示。前24位由IEEE决定如何分配,后24位由实际生产该网络设备的厂商自行指定。
               ff:  ff:  ff: ff: ff: ff     是广播地址;
             01:xx:xx:xx:xx:xx   是多播地址;
             01:00:5e:xx:xx:xx  是IPv4多播地址。

1、组播IP地址范围:224.0.0.0 ~ 239.255.255.255
       组播以太网地址(MAC地址):开头高三个字节是01:00:5e

2、组播分为两部分:
       组播数据流:目的
       组播控制流:(IGMP)分三种报文:report(join),leave,query

3、组播编程

int getsockopt(int sockfd, int level, int optname,void *optval, socklen_t *optlen);
int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);

 

      client:1、IP_MULTICAST_LOOP
                 2、IP_ADD_MEMBERSHIP
                 3、IP_DROP_MEMBERSHIP

netinet/in.h

/* Internet address.  */
typedef uint32_t in_addr_t;
struct in_addr
  {
    in_addr_t s_addr;
  };

#ifdef __USE_MISC
/* IPv4 multicast request.  */
struct ip_mreq
  {
    /* IP multicast address of group.  */
    struct in_addr imr_multiaddr;

    /* Local IP address of interface.  */
    struct in_addr imr_interface;
  };
	内容:组播客户端
	要求:接收组播发布的消息,接收5次自动退出;
 ************************************************************************/
#include<stdio.h>
#include<string.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<errno.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#define MULTICAST_IP "224.255.255.255"
#define PORT 6667
int main(int argc,char *argv[])
{
	int sockfd;
	int i;
	int addrlen,recvbytes,localen;
	int opterr1,opterr2,opterr3,binderr;
	int loopopt = 1;
	int opt = 1;
	char recvbuf[128];
	struct sockaddr_in local ;
	struct ip_mreq  mcast_addr;
	addrlen = sizeof(struct ip_mreq);
	localen = sizeof(local);
	sockfd =socket(AF_INET,SOCK_DGRAM,0);//建立socket
	if(sockfd ==-1)
	{
		printf("creat socket error,errno:%d\n",errno);
		return -1;
	}
        //套接字设为可重用
	opterr1 = setsockopt(sockfd ,SOL_SOCKET ,SO_REUSEADDR, &opt,sizeof(opt));
	if(opterr1< 0 )
	{
		perror("setsockopt1 error:\n");
	}
        //禁止组播数据回送
	opterr2 = setsockopt(sockfd ,IPPROTO_IP ,IP_MULTICAST_LOOP,
			&loopopt,sizeof(loopopt));
	if(opterr2< 0 )
	{
		perror("setsockopt2 error:\n");
	}

	bzero(&local ,sizeof(local));
	local.sin_family = AF_INET;
	local.sin_addr.s_addr = htonl(INADDR_ANY);
	local.sin_port = htons(PORT);

	bzero(&mcast_addr,addrlen);
	mcast_addr.imr_multiaddr.s_addr = inet_addr(MULTICAST_IP);
	mcast_addr.imr_interface.s_addr = htonl(INADDR_ANY);
        //将套接字与本地地址绑定
	binderr = bind(sockfd,(struct sockaddr *)&local ,localen);
	if(binderr < 0)
	{
		perror("Bind err:\n");
		close(sockfd);
	}
        //加入组播组
	opterr3 = setsockopt(sockfd ,IPPROTO_IP ,IP_ADD_MEMBERSHIP,
			&mcast_addr, addrlen);
	if(opterr3 < 0 )
	{
		perror("setsockopt3 error:\n");
	}
        //5次循环读取组播客户端发来的数据
	for(i =0 ;i < 5 ;i++)
	{
		bzero(recvbuf, 128 );

		recvbytes = recvfrom(sockfd,recvbuf,sizeof(recvbuf),0,(struct sockaddr*)(&local),&localen);
		if(recvbytes< 0)
		{
			perror("recv msg error.\n");
		}

		printf("%d time recv msg:%s\n",i,recvbuf);
		sleep(1);
	}
        //读取完毕,退出组播组,结束
	setsockopt(sockfd ,IPPROTO_IP ,IP_DROP_MEMBERSHIP,
			&mcast_addr, addrlen);
	close(sockfd);
	return 0;

}
	内容:编写以组播服务器
	要求:定期发送一组数据给加入组播组的所有客户端
 ************************************************************************/
#include<stdio.h>
#include<string.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<errno.h>
#include<string.h>
#include<unistd.h>
#define PORT 6667
#define MULTICAST_IP "224.255.255.255"
int main(int argc,char *argv[])
{
	int sockfd;
	int mcastlen,sendbytes;
	int opterr;
	int opt = 1;
	char sendbuf[128] = "Hello,I am multicast server!welcom to join me!";
	struct sockaddr_in mcast_addr;
	//建立socket
	mcastlen = sizeof(mcast_addr);
	sockfd =socket(AF_INET,SOCK_DGRAM,0);
	if(sockfd ==-1)
	{
		printf("creat socket error,errno:%d\n",errno);
		return -1;
	}
	opterr = setsockopt(sockfd ,SOL_SOCKET ,SO_REUSEADDR, &opt,sizeof(opt));
	if(opterr< 0 )
	{
		perror("setsockopt error:\n");
	}
	bzero(&mcast_addr,mcastlen);
	mcast_addr.sin_family = AF_INET;
	mcast_addr.sin_port = htons(PORT);
	mcast_addr.sin_addr.s_addr = inet_addr(MULTICAST_IP);
	while(1)
	{
		sendbytes = sendto(sockfd,sendbuf,strlen(sendbuf),0,(struct sockaddr*)(&mcast_addr),mcastlen);
		if(sendbytes<0)
		{
			perror("send msg error.\n");
		}
		printf("send msg success!\n");
		sleep(1);
	}

	return 0;

}


参考资料:
 1、 linux网络编程之-----多播(组播)编程

 

 

 

    

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值