组播发送端接收端,广播发送端接收端
1. 组播
1)概念
1. 广播方式是发送给同一网段下的所有主机,过多的广播会占用大量网络带宽,会造成广播风暴,影 响正常通讯;
2. 主机之间一对一组的通讯模式,也就是只有加入了同一个组的主机可以接收到此组内的所有数据;
3. 网络中的交换机和路由器只向需求者复制并转发数据;
4. 组播IP地址: D类IP地址: 224.0.0.0~239.255.255.255
2)组播的发送端流程(类似客户端)
1. 创建报式套接字 (socket)
2. 可选择绑定也可以不绑定地址信息结构体 (bind)
3. 填充接收方的IP地址及端口:IP地址:组播IP地址(224.0.0.0~239.255.255.255)
4. 发送数据(sendto)
3)组播的接收端流程 (类似服务器)
1. 创建报式套接字 (socket)
2. 加入多播组 (setsockopt)
3. 必须绑定地址信息结构体:IP地址:绑定组播IP地址(例如:224.1.2.3 或者 0.0.0.0)和端口 (bind) 注意:绑定的组播IP和端口号必须与发送方填充的一致;
4. 等待接收数据(recvfrom)
4)如何加入多播组
功能:获取和设置网络属性;
头文件:
#include<sys/types.h> /* See NOTES */
#include<sys/socket.h>
原型:
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); 参数:
int sockfd:指定要设置属性的套接字;
int level:指定要控制套接字的层次;
IPPROTO_IP: IP选项; man 7 ip
int optname:指定控制方式;
IP_ADD_MEMBERSHIP
void *optval:根据optname的不同,数据类型不同;
struct ip_mreqn {
struct in_addr imr_multiaddr; //组播Ip地址的网络字节序
struct in_addr imr_address; //本机IP地址的网络字节序
int imr_ifindex; //当前使用的网络设备索引号
/*1.ifconfig 找到网卡名 例如:"ens33".
ip ad 找到"ens33"对应的索引号,例如:2
2.通过函数的方式查找
if_nametoindex(网卡的名字); 例如:
if_nametoindex("ens33");
3.填0,默认索引号*/
};
socklen_t optlen:optval指向的变量的大小;
返回值:
成功,返回0;
失败,返回-1,更新errno;
5)发送端代码
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include <unistd.h>#define ERR_MSG(msg) do{\
printf("line = %d\n", __LINE__);\
perror(msg); \
}while(0)#define GRP_IP "224.1.2.3" //宏定义组播IP
#define GRP_POINT 2222 //宏定义端口号 与接收方端口号一致int main(int argc, char const *argv[])
{//创建报式套接字int sockfd = socket(AF_INET,SOCK_DGRAM,0);if(-1 == sockfd){ //如果创建失败ERR_MSG("socket"); //输出错误return -1;}printf("client created socket success\n"); //创建套接字成功输出提示//绑定服务器的ip和端口//结构体初始化struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(GRP_POINT);addr.sin_addr.s_addr = inet_addr(GRP_IP);socklen_t addrlen = sizeof(addr);char buf[32] = ""; //发送消息存储的字符串while (1){//发送信息给接收端bzero(buf,sizeof(buf)); //清空字符串printf("请输入发送给接收方的信息:");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1] = 0; //将从终端收到的消息\n改为\0ssize_t resend = sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&addr,addrlen); //发送buf中的信息给接收端if(-1 == resend){ //如果发送失败ERR_MSG("send"); //输出错误return -1;}printf("sendto success\n"); //发送成功输出提示}//关闭套接字close(sockfd);printf("exit\n");return 0;
}
6)接收端代码
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include <unistd.h>
#include<net/if.h>#define ERR_MSG(msg) do{\
printf("line = %d\n", __LINE__);\
perror(msg); \
}while(0)#define GRP_IP "224.1.2.3" //宏定义接收端组播IP
#define GRP_POINT 2222 //宏定义接收端端口int main(int argc, char const *argv[])
{//创建报式套接字int sockfd = socket(AF_INET,SOCK_DGRAM,0);if(-1 == sockfd){ //如果创建失败ERR_MSG("socket"); //输出错误return -1;}printf("Server created socket success\n"); //创建套接字成功输出提示//绑定接收端的ip和端口//结构体初始化struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(GRP_POINT);addr.sin_addr.s_addr = inet_addr(GRP_IP);socklen_t addrlen = sizeof(addr);int rb = bind(sockfd,(struct sockaddr*)&addr,addrlen);if(-1 == rb){ //如果绑定失败ERR_MSG("bind"); //输出错误return -1;}printf("bind success\n"); //套接字与服务端ip和端口绑定成功输出提示//加入多播组struct ip_mreqn mq;mq.imr_multiaddr.s_addr = inet_addr(GRP_IP); //组播IPmq.imr_address.s_addr = inet_addr("192.168.8.120"); //本机ipmq.imr_ifindex = if_nametoindex("ens33"); //网卡设备索引号if(setsockopt(sockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mq,sizeof(mq)) < 0){ //加入多播组ERR_MSG("setsockopt");return -1;}//接收发送端的信息char buf[32] = ""; //接收发送端发来消息存储的字符串ssize_t res = 0;struct sockaddr_in actaddr; //定义接收客户端ip和端口号的结构体socklen_t actaddrlen = sizeof(actaddr);while (1){ bzero(buf,sizeof(buf)); //清空字符串,接收客户端发来的消息ssize_t srecv = recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&actaddr,&addrlen);if(-1 == srecv){ ERR_MSG("recv"); //接收失败输出错误return -1;}printf("Server recv [%s: %d]: %s success\n",inet_ntoa(actaddr.sin_addr),ntohs(actaddr.sin_port),buf);//打印发送端ip、端口号和发来的消息}//关闭套接字close(sockfd);printf("exit\n");return 0;
}
2. 广播
1)概念
1. 主机之间一对多的通信方式,网络对其中每一台主机发出的信息都进行无条件复制并转发;
2. 所有主机都可以接收到所有信息,无论你是否需要,由于其不用路径选择,所以其网络成本比较 低;
3. 禁止广播数据穿过路由器,防止广播数据造成大面积影响
4. 只有UDP才能广播
5. 广播的地址:主机号全是1
192.168.1.41那么他的广播地址192.168.1.255;
255.255.255.255 给所有网段中的所有主机发送广播,但是由于广播数据不能穿过路由器,所以实 际上是给当前局域网下的主机发送;
2)广播的发送端流程(类似客户端)
1. 创建报式套接字 (socket)
2. 可选择绑定也可以不绑定地址信息结构体 (bind)
3. 设置网络属性:允许广播,如果不设置,默认是不允许的(setsockopt)
4. 填充广播的地址信息结构体:端口号 IP地址(广播IP 例如192.168.1.255 255.255.255.255)
5. 发送数据 (sendto)
3)广播的接收端流程(类似服务器)
1. 创建报式套接字 (socket)
2. 必须绑定地址信息结构体:绑定广播IP地址(192.168.1.255 或者 0.0.0.0)和 端口号 (bind) 注意:绑定的端口号必须和发送端填充的端口号一致;
3. 等待接收数据(recvfrom)
4)发送方代码
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include <unistd.h>#define ERR_MSG(msg) do{\
printf("line = %d\n", __LINE__);\
perror(msg); \
}while(0)#define IP "192.168.8.255" //宏定义接收端IP
#define POINT 2222 //宏定义接收端端口int main(int argc, char const *argv[])
{//创建报式套接字int sockfd = socket(AF_INET,SOCK_DGRAM,0);if(-1 == sockfd){ //如果创建失败ERR_MSG("socket"); //输出错误return -1;}printf("client created socket success\n"); //创建套接字成功输出提示//绑定接收端的ip和端口//结构体初始化struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(POINT);addr.sin_addr.s_addr = inet_addr(IP);socklen_t addrlen = sizeof(addr);//设置广播int broadcast = 1;socklen_t broadcast_len = sizeof(broadcast);if(setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&broadcast,broadcast_len) < 0){perror("setsockopt");return -1;}printf("broadcast set success\n");char buf[32] = ""; //存储发送端发出消息的字符串while (1){//发送信息给接收端bzero(buf,sizeof(buf)); //清空字符串printf("请输入发送给接收方的信息:");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1] = 0; //将从终端收到的消息\n改为\0ssize_t resend = sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&addr,addrlen); //发送buf中的信息给接收端if(-1 == resend){ //如果发送失败ERR_MSG("send"); //输出错误return -1;}printf("sendto success\n"); //发送成功输出提示}//关闭套接字close(sockfd);printf("exit\n");return 0;
}
5)接收方代码
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include <unistd.h>#define ERR_MSG(msg) do{\
printf("line = %d\n", __LINE__);\
perror(msg); \
}while(0)#define IP "192.168.8.255" //宏定义接收端私网
#define POINT 2222 //宏定义接收端端口int main(int argc, char const *argv[])
{//创建报式套接字int sockfd = socket(AF_INET,SOCK_DGRAM,0);if(-1 == sockfd){ //如果创建失败ERR_MSG("socket"); //输出错误return -1;}printf("created socket success\n"); //创建套接字成功输出提示//绑定接收端的ip和端口//结构体初始化struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(POINT);addr.sin_addr.s_addr = inet_addr(IP);socklen_t addrlen = sizeof(addr);int rb = bind(sockfd,(struct sockaddr*)&addr,addrlen);if(-1 == rb){ //如果绑定失败ERR_MSG("bind"); //输出错误return -1;}printf("bind server success\n"); //套接字与服务端ip和端口绑定成功输出提示//接收发送端的信息char buf[32] = ""; //接收发送端发来消息存储的字符串ssize_t res = 0;struct sockaddr_in actaddr; //定义接收发送端ip和端口号的结构体socklen_t actaddrlen = sizeof(actaddr);while (1){bzero(buf,sizeof(buf)); //清空字符串,接收发送端发来的消息ssize_t srecv = recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&actaddr,&addrlen);if(-1 == srecv){ ERR_MSG("recv"); //接收失败输出错误return -1;}printf("recv [%s: %d]: %s success\n",inet_ntoa(actaddr.sin_addr),ntohs(actaddr.sin_port),buf);}//关闭套接字close(sockfd);printf("exit\n");return 0;
}
组播发送端接收端,广播发送端接收端相关推荐
- 网络编程:组播发送接收
组播发送 *********************************************************************************************** ...
- UDP接收端和发送端_Socket编程
UDP接收端 接收端启动文件 1 import java.net.DatagramSocket; 2 import java.net.SocketException; 3 4 public class ...
- iOS14 广播组播发送失败问题
我们App之前用到广播组播发送配网信息,然后设备收到信息后自动配网的功能.在iOS14以后的版本突然失效.调试发现是发送广播包一直失败,组播包也没发送成功.查阅了相关资料,发现需要申请一个广播包发送的 ...
- Linux组播编程 组播发送和组播接收
接收端 int init_recv_socket(int *pSockfd) {int recv_sockfd = -1;struct ip_mreq mreq;bzero(&mreq, si ...
- 高速串行信号串接电容放在发送端还是接收端
在设计一些高速的串行信号,比如PCIE,STATA,USB3.0等,在差分信号线上面常常都会串接一个电容 这个电容主要有如下几个方面的作用: 1.滤除信号的直流分量,使信号关于0电平对称: 因为很多高 ...
- 如何实现WiFi Display互联:我的一次WiFi Display(Miracast)功能发送端(source)和接收端(sink)的实现笔记
https://blog.csdn.net/xmc281141947/article/details/60573311/ 公司业务需要在安卓车载产品和手机端实现WiFi Display(Miracas ...
- UDP 实现多收多发,广播发送,组播发送 TCP 实现多收多发
文章目录 TCP 实现多收多发(上线下线提醒) UDP多收多发 UDP广播发送接收 UDP 组播发送接收 TCP 实现多收多发(上线下线提醒) 创建发送端 public static void mai ...
- stm32f103c8t6与stm32f103zet6 基于SX1276串口通信-----发送端(一)
STM32发送端的设计 发送端采用stm32f103c8t6为主控设计,采用矩阵按键作为发送输入端,进行信号传入. 如下图可以看出模块主要采用的是泽耀SX1276无线模块,频段采用433MHz ##接 ...
- linux配组播ip地址,linux 广播和组播
广播和组播 广播,必须使用UDP协议,是只能在局域网内使用,指定接收端的IP为*.*.*.255后,发送的信息,局域网内的所有接受端就能够接到信息了. 广播的发送端代码 #include #inclu ...
最新文章
- 残差网络的前世今生与原理 | 赠书
- 如何使用华为云的计算资源进行深度学习(ModelArts)
- C#读取Win32标准DLL文件中的字符串资源
- KVM中virtio实现(九)
- 修改jupyter的保存位置
- 致NLP学习者,该跟大佬学习做项目了,附资料
- mysql id 字段类型转换_mysql 数据类型转换
- python调用qt动态库_QT开发——动态库(.so文件)的生成与调用
- [原创]UUID的介绍和使用
- html页面div等分,HTML5使用纯CSS实现“按比例平分”整个垂直空间
- Mbs Framework 简介
- 基于Tomcat + JNDI + ActiveMQ实现JMS的点对点消息传送
- TCP 之 抓包分析
- Android APP微信第三方登录踩坑 - 微信开放平台修改应用包名后微信第三方登录失败
- 关于新版微信电脑版HOOK的技术经验(WX电脑版3.0)
- 【Python】多进程 AttributeError: Can‘t pickle local object
- @Zabbix配置邮箱告警及钉钉告警
- Ubuntu-安装汉语拼音输入法
- Elasticsearch Kibana Filebeat开启SSL通信
- Linux全面解析讲解