当前位置: 首页 > news >正文

UDP通信 单播,广播,组播

UDP通信实现

image-20240729160530205
#include <sys/types.h>
#include <sys/socket.h>
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
- 参数:
struct sockaddr *src_addr, socklen_t *addrlen)- sockfd : 通信的fd- buf : 要发送的数据- len : 发送数据的长度- flags : 0- dest_addr : 通信的另外一端的地址信息- addrlen : 地址的内存大小ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
;
- 参数:
- sockfd : 通信的fd
- buf : 接收数据的数组
- len : 数组的大小
- flags : 0
- src_addr : 用来保存另外一端的地址信息,不需要可以指定为NULL
- addrlen : 地址的内存大小
案例
udp_server.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>int main() {// 1.创建一个通信的socketint fd = socket(PF_INET, SOCK_DGRAM, 0);if(fd == -1) {perror("socket");exit(-1);}   struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(9999);addr.sin_addr.s_addr = INADDR_ANY;// 2.绑定int ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));if(ret == -1) {perror("bind");exit(-1);}// 3.通信while(1) {char recvbuf[128];char ipbuf[16];struct sockaddr_in cliaddr;int len = sizeof(cliaddr);// 接收数据int num = recvfrom(fd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&cliaddr, &len);printf("client IP : %s, Port : %d\n", inet_ntop(AF_INET, &cliaddr.sin_addr.s_addr, ipbuf, sizeof(ipbuf)),ntohs(cliaddr.sin_port));printf("client say : %s\n", recvbuf);// 发送数据sendto(fd, recvbuf, strlen(recvbuf) + 1, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));}close(fd);return 0;
}
udp_client.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>int main() {// 1.创建一个通信的socketint fd = socket(PF_INET, SOCK_DGRAM, 0);if(fd == -1) {perror("socket");exit(-1);}   // 服务器的地址信息struct sockaddr_in saddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(9999);inet_pton(AF_INET, "127.0.0.1", &saddr.sin_addr.s_addr);int num = 0;// 3.通信while(1) {// 发送数据char sendBuf[128];sprintf(sendBuf, "hello , i am client %d \n", num++);sendto(fd, sendBuf, strlen(sendBuf) + 1, 0, (struct sockaddr *)&saddr, sizeof(saddr));// 接收数据int num = recvfrom(fd, sendBuf, sizeof(sendBuf), 0, NULL, NULL);printf("server say : %s\n", sendBuf);sleep(1);}close(fd);return 0;
}

广播

向子网中多台计算机发送消息,并且子网中所有的计算机都可以接收到发送方发送的消息,每个广播消息都包含一个特殊的IP地址,这个IP中子网内主机标志部分的二进制全部为1。

a.只能在局域网中使用。

b.客户端需要绑定服务器广播使用的端口,才可以接收到广播消息。

image-20240729161359709

image-20240729180754007

// 设置广播属性的函数
int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t
optlen);
- sockfd : 文件描述符
- level : SOL_SOCKET
- optname : SO_BROADCAST
- optval : int类型的值,为1表示允许广播
- optlen : optval的大小
案例
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>/*** 主函数:实现UDP广播发送消息* 创建一个UDP套接字,并配置为广播类型,然后循环向指定广播地址发送消息。*/
int main() {// 创建一个UDP类型的套接字// 1.创建一个通信的socketint fd = socket(PF_INET, SOCK_DGRAM, 0);if(fd == -1) {perror("socket");exit(-1);}   // 设置套接字选项,允许发送广播消息// 2.设置广播属性,设置为广播就不需要再绑定了,因为只发送数据int op = 1;setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &op, sizeof(op));// 初始化客户端地址结构体,设置为广播地址// 3.创建一个广播的地址struct sockaddr_in cliaddr;cliaddr.sin_family = AF_INET;cliaddr.sin_port = htons(9999);inet_pton(AF_INET, "192.168.220.255", &cliaddr.sin_addr.s_addr);// 循环发送消息// 3.通信int num = 0;while(1) {// 准备发送的消息,包含消息编号char sendBuf[128];sprintf(sendBuf, "hello, client....%d\n", num++);// 发送消息到广播地址// 发送数据sendto(fd, sendBuf, strlen(sendBuf) + 1, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));printf("广播的数据:%s\n", sendBuf);// 休眠1秒后继续发送sleep(1);}// 关闭套接字close(fd);return 0;
}

组播(多播)

单播地址标识单个 IP 接口,广播地址标识某个子网的所有 IP 接口,多播地址标识一组 IP 接口。单播和广播是寻址方案的两个极端(要么单个要么全部),多播则意在两者之间提供一种折中方案。多播数据报只应该由对它感兴趣的接口接收,也就是说由运行相应多播会话应用系统的主机上的接口接收。另外,广播一般局限于局域网内使用,而多播则既可以用于局域网,也可以跨广域网使用。

a.组播既可以用于局域网,也可以用于广域网

b.客户端需要加入多播组,才能接收到多播的数据

image-20240729181113291

组播地址

IP 多播通信必须依赖于 IP 多播地址,在 IPv4 中它的范围从 224.0.0.0 到 239.255.255.255 ,

并被划分为局部链接多播地址、预留多播地址和管理权限多播地址三类:

image-20240729181136229

int setsockopt(int sockfd, int level, int optname,const void *optval,
socklen_t optlen);
// 服务器设置多播的信息,外出接口
- level : IPPROTO_IP
- optname : IP_MULTICAST_IF
- optval : struct in_addr
// 客户端加入到多播组:
- level : IPPROTO_IP
- optname : IP_ADD_MEMBERSHIP
- optval : struct ip_mreq
struct ip_mreq
{
/* IP multicast address of group. */
struct in_addr imr_multiaddr; // 组播的IP地址
/* Local IP address of interface. */
struct in_addr imr_interface; // 本地的IP地址
};
typedef uint32_t in_addr_t;
struct in_addr
{
in_addr_t s_addr;
};

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 独立3D网络游戏《战域重甲》开发与上架经验分享
  • KDP开源平台升级,推进大数据处理迈向轻量化、智能化
  • LUA脚本改造redis分布式锁
  • C++ 基础(类和对象下)
  • 一个简单的数据库连接池示例
  • golang 文件
  • 华为od 100问 持续分享10-华为OD的面试流程细说
  • Linux--序列化与反序列化
  • linux安装jdk和jps(为rocketMq准备)
  • Rust配置国内源,解决安装依赖慢问题
  • Spring缓存注解
  • Unity3D 自定义Debug双击溯源问题详解
  • 基于bert的自动对对联系统
  • Java8 新特性,看这篇文章就够了
  • 算法-插入排序
  • Apache的80端口被占用以及访问时报错403
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • Java,console输出实时的转向GUI textbox
  • js写一个简单的选项卡
  • Linux快速复制或删除大量小文件
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • October CMS - 快速入门 9 Images And Galleries
  • Python十分钟制作属于你自己的个性logo
  • Solarized Scheme
  • Webpack 4x 之路 ( 四 )
  • 初识MongoDB分片
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 浮动相关
  • 基于webpack 的 vue 多页架构
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 腾讯视频格式如何转换成mp4 将下载的qlv文件转换成mp4的方法
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 网页视频流m3u8/ts视频下载
  • 详解NodeJs流之一
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • PostgreSQL之连接数修改
  • 策略 : 一文教你成为人工智能(AI)领域专家
  • ​LeetCode解法汇总518. 零钱兑换 II
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • (02)vite环境变量配置
  • (HAL库版)freeRTOS移植STMF103
  • (ros//EnvironmentVariables)ros环境变量
  • (windows2012共享文件夹和防火墙设置
  • (纯JS)图片裁剪
  • (带教程)商业版SEO关键词按天计费系统:关键词排名优化、代理服务、手机自适应及搭建教程
  • (第27天)Oracle 数据泵转换分区表
  • (二)丶RabbitMQ的六大核心
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (论文阅读26/100)Weakly-supervised learning with convolutional neural networks
  • (实战)静默dbca安装创建数据库 --参数说明+举例
  • (四)进入MySQL 【事务】
  • (学习日记)2024.01.19
  • (转)德国人的记事本
  • ***linux下安装xampp,XAMPP目录结构(阿里云安装xampp)