ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Linux网络编程——广播、多播

2020-12-10 09:33:32  阅读:192  来源: 互联网

标签:多播 addr int IP 编程 Linux sockfd include


广播和多播编程都是建立在UDP通信的基础上,通过setsockopt函数即可发送广播数据报或多播数据报。

 

int setsockopt(int fd,int level,int optname,const char*optval,int optlen)

参数:1、套接字描述符

   2、选项定义层次,可为SOL_SOCKET、IPPROTO_TCP、IPPROTO_IP。在广播中使用SOL_SOCKET

   3、根据第二个参数,可为不同的值,在选定SOL_SOCKET的前提下,可为

    SO_BROADCAST:允许发送广播数据报

    SO_RCVBUF:接受缓冲区大小

    SO_SNDBUF:发送缓冲区大小

   4、第三个参数的长度

用于设置状态字的选项值设置。成功返回0,失败返回-1

广播:

接受方

 1 #include<iostream>
 2 #include<arpa/inet.h>
 3 #include<stdio.h>
 4 #include<string.h>
 5 #include<sys/socket.h>
 6 #include<sys/types.h>
 7 #include<netinet/in.h>
 8 #include<unistd.h>
 9 using namespace std;
10 
11 int main()
12 {
13     struct sockaddr_in addr,recvaddr;
14     socklen_t len=sizeof(recvaddr);
15     int sockfd,op;
16     char buf[512];
17 
18     sockfd=socket(AF_INET,SOCK_DGRAM,0);
19     if(sockfd<0)
20     {
21         cout<<"socket error"<<endl;
22         return -1;
23     }
24 
25     addr.sin_family=AF_INET;
26     addr.sin_port=htons(2501);
27     addr.sin_addr.s_addr=htons(INADDR_ANY);
28 
29     op=bind(sockfd,(struct sockaddr*)&addr,sizeof(addr));
30     if(op<0)
31     {
32         cout<<"bind error"<<endl;
33         return -1;
34     }
35 
36     recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&recvaddr,&len);
37     cout<<"recv data from "<<ntohs(recvaddr.sin_port)<<" :"<<buf<<endl;
38 
39     //char buff[512]="1234567890987654321";
40     //sendto(sockfd,buff,strlen(buff),0,(struct sockaddr*)&recvaddr,len);
41     return 0;
42 }

发送广播数据:

 1 #include<sys/socket.h>
 2 #include<sys/types.h>
 3 #include<iostream>
 4 #include<stdio.h>
 5 #include<stdlib.h>
 6 #include<string.h>
 7 #include<netinet/in.h>
 8 #include<arpa/inet.h>
 9 using namespace std;
10 
11 int main()
12 {
13     int sockfd;
14     int op;
15     struct sockaddr_in addr,saddr;
16     socklen_t len=sizeof(saddr);
17     int i,j;
18 
19     sockfd=socket(AF_INET,SOCK_DGRAM,0);
20     if(sockfd<0)
21     {
22         cout<<"socket error"<<endl;
23         return -1;
24     }
25 
26     addr.sin_family=AF_INET;
27     addr.sin_port=htons(2501);
28     addr.sin_addr.s_addr=htons(INADDR_ANY);
29 
30     int yes=1;
31     setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&yes,sizeof(yes));
32     char buff[512]="0987654321234567890";
33     sendto(sockfd,buff,strlen(buff),0,(struct sockaddr*)&addr,sizeof(addr));
34     cout<<"send: "<<buff<<endl;
35 
36     return 0;
37 }

 

多播:

广播会向同一子网的主机发送消息,有时候会严重浪费网络带宽;而多播则只会向出于同一多播组的主机发送消息。

这里先说一下IPv4多播地址结构体:

struct in_addr

{

  in_addr_t   s_addr;

}

sturct ip_mreq

{

  struct in_addr imr_multiaddr;//多播组IP,类似QQ中的QQ群号,范围224.0.0.0到239.255.255.255其中224.0.0.0不可取

  struct in_addr imr_interface;//要加入多播组的IP

}

int setsockopt(int fd,int level,int optname,const char*optval,int optlen)

参数:1、套接字描述符

   2、选项定义层次,可为SOL_SOCKET、IPPROTO_TCP、IPPROTO_IP。在多播中使用IPPROTO_IP

   3、根据第二个参数,可为不同的值,在选定IPPROTO_IP的前提下,可为

    IP_ADD_MEMBERSHIP:加入多播组

    IP_DROP_MEMBERSHIP:离开多播组

    IP_MULTICAST_LOOP:设置回环许可,即自己发送的多播数据会发送到本地回环接口

   4、第三个参数的长度

用于设置状态字的选项值设置。成功返回0,失败返回-1

广播:

接受方

 1 #include<sys/socket.h>
 2 #include<sys/types.h>
 3 #include<iostream>
 4 #include<stdio.h>
 5 #include<stdlib.h>
 6 #include<string.h>
 7 #include<netinet/in.h>
 8 #include<arpa/inet.h>
 9 #include<errno.h>
10 #include<unistd.h>
11 using namespace std;
12 
13 int main(int argc,char**argv)
14 {
15     int sockfd;
16     int op;
17     struct sockaddr_in addr,saddr;
18     socklen_t len=sizeof(saddr);
19     int i,j;
20 
21     sockfd=socket(AF_INET,SOCK_DGRAM,0);
22     if(sockfd<0)
23     {
24         cout<<"socket error"<<endl;
25         return -1;
26     }
27 
28     memset(&addr,0,sizeof(addr));
29     addr.sin_family=AF_INET;
30     addr.sin_port=htons(8000);//多播服务器端口,使用别的端口会返回errno=22
31     addr.sin_addr.s_addr=htonl(INADDR_ANY);
32     op=bind(sockfd,(struct sockaddr*)&addr,sizeof(addr));
33     if(op<0)
34     {
35         cout<<"bind error"<<endl;
36         return 0;
37     }
38     
39     int yes=1;
40     op=setsockopt(sockfd,IPPROTO_IP,IP_MULTICAST_LOOP,&yes,sizeof(yes));//设置回环许可
41     if(op<0)
42     {
43         cout<<"set LOOP error"<<endl;
44         return 0;
45     }
46     struct ip_mreq mreq;
47     bzero(&mreq,sizeof(mreq));
48     mreq.imr_multiaddr.s_addr=inet_addr("224.0.0.88");
49     mreq.imr_interface.s_addr=htonl(INADDR_ANY);
50     
51     op=setsockopt(sockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char*)&mreq,sizeof(mreq));
52     if(op<0)
53     {
54         cout<<errno<<endl;
55         return 0;
56     }
57     
58     char buff[512];
59     char recv_buff[512]="";
60     cout<<"111"<<endl;
61     for(i=1;i<=5;i++)
62     {
63         sleep(3);
64         memset(recv_buff,0,sizeof(recv_buff));
65         len=sizeof(addr);
66         recvfrom(sockfd,recv_buff,sizeof(recv_buff),0,(struct sockaddr*)&addr,&len);
67         cout<<"recv: "<<recv_buff<<endl;
68     }
69 
70     return 0;
71 }

发送方:

 1 #include<sys/socket.h>
 2 #include<sys/types.h>
 3 #include<iostream>
 4 #include<stdio.h>
 5 #include<stdlib.h>
 6 #include<string.h>
 7 #include<netinet/in.h>
 8 #include<arpa/inet.h>
 9 #include<errno.h>
10 #include<unistd.h>
11 using namespace std;
12 int main()
13 {
14     struct sockaddr_in addr;
15     socklen_t len;
16     int i,j;
17     int sockfd=socket(AF_INET,SOCK_DGRAM,0);
18     addr.sin_family=AF_INET;
19     addr.sin_port=htons(8000);//多播服务器端口
20     addr.sin_addr.s_addr=inet_addr("224.0.0.88");
21     
22     char buff[512]="123456789";
23     for(i=9;i<=14;i++)
24     {
25         sleep(3);
26         buff[i]=(i-8)+'0';
27         buff[i+1]=0;
28         len=sizeof(addr);
29         sendto(sockfd,buff,strlen(buff),0,(struct sockaddr*)&addr,sizeof(addr));
30         cout<<"1111"<<endl;
31         
32     }
33     return 0;
34     
35 }

参考书籍——《Linux网络编程》

标签:多播,addr,int,IP,编程,Linux,sockfd,include
来源: https://www.cnblogs.com/Aaiu1201/p/14112050.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有