专注网站建设,专业做家电经销的网站,佛山网站优化推广方案,深圳设计网站建设公司目录
前言 二、多点通信
2.1 单播
2.2 广播
2.2.1 广播得发送端实现--》类似与UDP的客户端 2.3 组播
2.3.1 组播发送端流程--》类似于UDP的客户端流程 2.3.2 组播的接收端流程---》类似于UDP的服务器端流程 前言
多点通信 一、套接字选项得获取和设置 int getsockopt(int…目录
前言 二、多点通信
2.1 单播
2.2 广播
2.2.1 广播得发送端实现--》类似与UDP的客户端 2.3 组播
2.3.1 组播发送端流程--》类似于UDP的客户端流程 2.3.2 组播的接收端流程---》类似于UDP的服务器端流程 前言
多点通信 一、套接字选项得获取和设置 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);功能获取或设置套接字在不同层级上的相关属性参数1要获取或设置的套接字文件描述符参数2表示要获取或设置的层应用层SOL_SOCKET传输层TCPIPPROTO_TCP传输层UDPIPPROTO_UDP网络层IPPROTO_IP参数3当前层的属性名称见下表所示参数4要获取或设置的属性值的起始地址参数5参数4的大小返回值成功返回0失败返回-1并置位错误码 1.代码演示
#includemyhead.hint main(int argc, const char *argv[])
{//1、创建一个套接字文件描述符int sfd socket(AF_INET, SOCK_STREAM, 0);if(sfd -1){perror(socket error);return -1;}//2、获取地址快速重用属性的值int res -1; //接收属性值int reslen sizeof(res); //接收属性的大小if(getsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, res, reslen)-1){perror(getsockopt error);return -1;}//程序执行至此就获取了默认是否能地址快速重用printf(res %d\n, res); //0表示默认不能快速重用//3\、设置地址能够快速重用int reuse 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, reuse, sizeof(reuse))-1){perror(setsockopt error);return -1;}//4、再重新获取一次判断是否设置成功res -1;if(getsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, res, reslen)-1){perror(getsockopt error);return -1;}//程序执行至此就获取了默认是否能地址快速重用printf(res %d\n, res); //1表示已经设置成功了return 0;
} 二、多点通信
2.1 单播
1.主机之间存在的是一对一的通信方式交换机以及路由器对数据只进行转发不进行复制
2.每次只有两个实体之间进行相互通信发送端和接收端都是唯一确定的
2.2 广播
1.广播是允许通信实体之间完成一对多的通信方式网络对其中每一台发送数据的主机信息都进行无条件的复制后并转发给其他所有主机
2.所有主机都会收到广播消息不管是都愿意接受
3.广播只能由UDP通信方式来实现
4.广播消息只能在当前网络下进行转播不允许传过路由器
5.广播地址网络号255
6.官博分为发送端和接收端实现
2.2.1 广播得发送端实现--》类似与UDP的客户端
1、创建用于通信的套接字文件描述符socket
2、设置该套接字允许发送广播消息setsockopt --- SOL_SOCKET --- SO_BROADCAST
3、绑定IP地址和端口号可选
4、向广播地址发送数据sendto广播地址IP网络号 255端口号与接收端保持一致
5、关闭套接字close
代码实现
#includemyhead.hint main(int argc, const char *argv[])
{//1、创建用于通信的套接字文件描述符int rfd socket(AF_INET, SOCK_DGRAM, 0);if(rfd -1){perror(socket error);return -1;}//2、填充地址信息结构体//ip广播地址//port与发送端保持一致struct sockaddr_in rin;rin.sin_family AF_INET;rin.sin_port htons(6666); //端口号rin.sin_addr.s_addr inet_addr(192.168.125.255); //广播ip地址//3、绑定端口号和IP地址必须if(bind(rfd, (struct sockaddr*)rin, sizeof(rin)) -1){perror(bind error);return -1;}//4、接受发送端发来的消息recvfromchar rbuf[128] ;while(1){//清空容器bzero(rbuf, sizeof(rbuf));//读取数据recv(rfd, rbuf, sizeof(rbuf), 0);//展示printf(收到广播消息%s\n, rbuf);//判断广播是否结束if(strcmp(rbuf, over) 0){break;}}//5、关闭套接字closeclose(rfd);return 0;
}
2.2.2 广播的接收端--》类似于UDP的服务器端
1、创建用于通信的套接字文件描述符
2、填充地址信息结构体ip广播地址port与发送端保持一致
3、绑定端口号和IP地址必须
4、接受发送端发来的消息recvfrom
5、关闭套接字close
代码实现 #includemyhead.hint main(int argc, const char *argv[])
{//1、创建用于通信的套接字文件描述符int rfd socket(AF_INET, SOCK_DGRAM, 0);if(rfd -1){perror(socket error);return -1;}//2、填充地址信息结构体//ip广播地址//port与发送端保持一致struct sockaddr_in rin;rin.sin_family AF_INET;rin.sin_port htons(6666); //端口号rin.sin_addr.s_addr inet_addr(192.168.125.255); //广播ip地址//3、绑定端口号和IP地址必须if(bind(rfd, (struct sockaddr*)rin, sizeof(rin)) -1){perror(bind error);return -1;}//4、接受发送端发来的消息recvfromchar rbuf[128] ;while(1){//清空容器bzero(rbuf, sizeof(rbuf));//读取数据recv(rfd, rbuf, sizeof(rbuf), 0);//展示printf(收到广播消息%s\n, rbuf);//判断广播是否结束if(strcmp(rbuf, over) 0){break;}}//5、关闭套接字closeclose(rfd);return 0;
}2.3 组播
1.由于广播通信过程中会占用大量的网络宽带影响正常通信如果通信的主机较少的话可以引入组播
2.组播也是实现主机之间一对多的通信方式
3.要求所有接收端主机加入多播组只有加入多播组的主机才能收到消息
4.对于发送端而言只需向该多组播中发送消息即可无需其他设置
5.组播也是使用UDP实现的
6.组播地址D类网络【224.0.0.0---239.255.255.255】
7.组播也分为发送端和接收端
2.3.1 组播发送端流程--》类似于UDP的客户端流程
1、创建用于通信的套接字文件描述符socket
2、绑定IP地址和端口号可选
3、向组播地址发送数据sendto广播地址IP【224.0.0.0 --- 239.255.255.255】端口号与接收端保持一致
4、关闭套接字close
代码实现 #includemyhead.hint main(int argc, const char *argv[])
{//1、创建用于通信的套接字文件描述符socketint sfd socket(AF_INET, SOCK_DGRAM, 0);if(sfd -1){perror(socket error);return -1;}//2、绑定IP地址和端口号可选//3、向组播地址发送数据sendto//广播地址IP【224.0.0.0 --- 239.255.255.255】//端口号与接收端保持一致struct sockaddr_in rin;rin.sin_family AF_INET;rin.sin_port htons(5555);rin.sin_addr.s_addr inet_addr(224.1.2.3);//数据的发送//发送数据char wbuf[128] ;while(1){//从终端获取数据fgets(wbuf, sizeof(wbuf), stdin);wbuf[strlen(wbuf)-1] 0;//发送给广播消息sendto(sfd, wbuf, strlen(wbuf), 0, (struct sockaddr*)rin, sizeof(rin));printf(发送成功\n);//判断发送的消息if(strcmp(wbuf, over) 0){break;}}//5、关闭套接字closeclose(sfd);return 0;
}2.3.2 组播的接收端流程---》类似于UDP的服务器端流程
1、创建用于通信的套接字文件描述符socket
2、将该套接字加入多播组setsockopt --- IPPROTO_IP -- IP_ADD_MEMBERSHIP
属性类型struct ip_mreqn {struct in_addr imr_multiaddr; /* 组播地址 */struct in_addr imr_address; /* 主机ip地址 */int imr_ifindex; /* 设备索引可以通过 ip ad指令查看 也可以填0表示使用默认的索引*/};3、填充地址信息结构体ip组播地址port与发送端保持一致
4、绑定端口号和IP地址必须
5、接受发送端发来的消息recvfrom
6、关闭套接字close
代码实现
#includemyhead.hint main(int argc, const char *argv[])
{//1、创建用于通信的套接字文件描述符socketint rfd socket(AF_INET, SOCK_DGRAM, 0);if(rfd -1){perror(socket error);return -1;}//2、将该套接字加入多播组setsockopt --- IPPROTO_IP -- IP_ADD_MEMBERSHIP struct ip_mreqn imr;imr.imr_multiaddr.s_addr inet_addr(224.1.2.3);imr.imr_address.s_addr inet_addr(192.168.125.113);imr.imr_ifindex 2;//设置套接字选项加入多播组if(setsockopt(rfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, imr, sizeof(imr))-1){perror(setsockopt error);return -1;}//3、填充地址信息结构体//ip组播地址//port与发送端保持一致struct sockaddr_in rin;rin.sin_family AF_INET;rin.sin_addr.s_addr inet_addr(224.1.2.3);rin.sin_port htons(5555);//4、绑定端口号和IP地址必须if(bind(rfd, (struct sockaddr*)rin, sizeof(rin)) -1){perror(bind error);return -1;}//5、接受发送端发来的消息recvfromchar rbuf[128] ;while(1){//清空容器bzero(rbuf, sizeof(rbuf));//读取数据recv(rfd, rbuf, sizeof(rbuf), 0);//展示printf(收到广播消息%s\n, rbuf);//判断广播是否结束if(strcmp(rbuf, over) 0){break;}}//6、关闭套接字closeclose(rfd);return 0;
}