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;
}

组播发送端接收端,广播发送端接收端相关推荐

  1. 网络编程:组播发送接收

    组播发送 *********************************************************************************************** ...

  2. UDP接收端和发送端_Socket编程

    UDP接收端 接收端启动文件 1 import java.net.DatagramSocket; 2 import java.net.SocketException; 3 4 public class ...

  3. iOS14 广播组播发送失败问题

    我们App之前用到广播组播发送配网信息,然后设备收到信息后自动配网的功能.在iOS14以后的版本突然失效.调试发现是发送广播包一直失败,组播包也没发送成功.查阅了相关资料,发现需要申请一个广播包发送的 ...

  4. Linux组播编程 组播发送和组播接收

    接收端 int init_recv_socket(int *pSockfd) {int recv_sockfd = -1;struct ip_mreq mreq;bzero(&mreq, si ...

  5. 高速串行信号串接电容放在发送端还是接收端

    在设计一些高速的串行信号,比如PCIE,STATA,USB3.0等,在差分信号线上面常常都会串接一个电容 这个电容主要有如下几个方面的作用: 1.滤除信号的直流分量,使信号关于0电平对称: 因为很多高 ...

  6. 如何实现WiFi Display互联:我的一次WiFi Display(Miracast)功能发送端(source)和接收端(sink)的实现笔记

    https://blog.csdn.net/xmc281141947/article/details/60573311/ 公司业务需要在安卓车载产品和手机端实现WiFi Display(Miracas ...

  7. UDP 实现多收多发,广播发送,组播发送 TCP 实现多收多发

    文章目录 TCP 实现多收多发(上线下线提醒) UDP多收多发 UDP广播发送接收 UDP 组播发送接收 TCP 实现多收多发(上线下线提醒) 创建发送端 public static void mai ...

  8. stm32f103c8t6与stm32f103zet6 基于SX1276串口通信-----发送端(一)

    STM32发送端的设计 发送端采用stm32f103c8t6为主控设计,采用矩阵按键作为发送输入端,进行信号传入. 如下图可以看出模块主要采用的是泽耀SX1276无线模块,频段采用433MHz ##接 ...

  9. linux配组播ip地址,linux 广播和组播

    广播和组播 广播,必须使用UDP协议,是只能在局域网内使用,指定接收端的IP为*.*.*.255后,发送的信息,局域网内的所有接受端就能够接到信息了. 广播的发送端代码 #include #inclu ...

最新文章

  1. 残差网络的前世今生与原理 | 赠书
  2. 如何使用华为云的计算资源进行深度学习(ModelArts)
  3. C#读取Win32标准DLL文件中的字符串资源
  4. KVM中virtio实现(九)
  5. 修改jupyter的保存位置
  6. 致NLP学习者,该跟大佬学习做项目了,附资料
  7. mysql id 字段类型转换_mysql 数据类型转换
  8. python调用qt动态库_QT开发——动态库(.so文件)的生成与调用
  9. [原创]UUID的介绍和使用
  10. html页面div等分,HTML5使用纯CSS实现“按比例平分”整个垂直空间
  11. Mbs Framework 简介
  12. 基于Tomcat + JNDI + ActiveMQ实现JMS的点对点消息传送
  13. TCP 之 抓包分析
  14. Android APP微信第三方登录踩坑 - 微信开放平台修改应用包名后微信第三方登录失败
  15. 关于新版微信电脑版HOOK的技术经验(WX电脑版3.0)
  16. 【Python】多进程 AttributeError: Can‘t pickle local object
  17. @Zabbix配置邮箱告警及钉钉告警
  18. Ubuntu-安装汉语拼音输入法
  19. Elasticsearch Kibana Filebeat开启SSL通信
  20. Linux全面解析讲解

热门文章

  1. 【显卡】AMD和Nvidia显卡系列相关对比(A100 vs RTX4090)
  2. 单对象编程实现2048小游戏!
  3. 维基百科里nbsp;的intjnbsp;amp;nbs…
  4. iOS 录音pcm获取当前音量
  5. Swift和OC,是编译型语言、解释性语言、运行时语言?
  6. 《机器学习算法竞赛实战》笔记 - 第一部分 磨刀事半,砍柴功倍
  7. 大数据:Kettle导入数据到HDFS
  8. InVEST模型——的人类活动、重大工程生态成效评估、论文写作
  9. JMS之ActiveMQ下载安装
  10. css旋转立方体教程,css 旋转立方体