UDP概念特点+编程流程
UDP概念+编程流程
目录
一、UDP基本概念
1.1 概念
1.2 特点
1.2.1 无连接性:
1.2.2 不可靠性
1.2.3 面向报文
二、UDP编程流程
2.1 客户端 cli.c
2.2 服务端ser.c
一、UDP基本概念
1.1 概念
UDP 即用户数据报协议(User Datagram Protocol ) ,是 OSI 参考模型中一种无连接的传输层协议,提供的是无连接,不可靠,数据报服务。
1.2 特点
1.2.1 无连接性:
UDP 传输数据之前源端和终端不建立连接,发送方直接将数据打包成 UDP 数据报发送到网络上,无需等待接收方确认,减少了开销和发送数据前的时延 。比如在线游戏中,玩家操作指令频繁发送,使用 UDP 可快速将指令发出,无需建立连接等待 。
1.2.2 不可靠性
UDP 不保证数据的可靠传输,不提供报文到达确认、排序及流量控制等功能 ,也没有数据包重传机制和错误恢复机制 。若传输中数据包丢失、损坏或乱序,UDP 不会自动处理 。像网络视频会议,偶尔丢包对整体影响不大,更看重实时性,就适合用 UDP 。
1.2.3 面向报文
UDP 对应用程序交下来的报文,在添加首部后就向下交付给 IP 层,既不拆分也不合并,保留报文边界 。这要求应用程序选择合适报文大小 。
二、UDP编程流程

2.1 客户端 cli.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>int main()
{// 创建一个 UDP 套接字,AF_INET 表示使用 IPv4 地址族,SOCK_DGRAM 表示使用 UDP 协议int sockfd = socket(AF_INET,SOCK_DGRAM,0); // 检查套接字是否创建成功,如果创建失败(返回值为 -1),则终止程序if( sockfd == -1 ) {exit(1);}// 定义一个 IPv4 套接字地址结构体,用于存储服务器地址信息struct sockaddr_in saddr; // 将服务器地址结构体 saddr 的内存空间清零memset(&saddr,0,sizeof(saddr)); // 设置地址族为 IPv4saddr.sin_family = AF_INET; // 将端口号 6000 从主机字节序转换为网络字节序saddr.sin_port = htons(6000); // 将 IP 地址 "127.0.0.1" 从点分十进制字符串转换为网络字节序的二进制数saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 进入无限循环,用于持续进行数据的发送和接收操作while( 1 ) {// 提示用户输入信息printf("input:\n"); // 定义一个字符数组,用于存储用户输入的数据,大小为 128 字节char buff[128] = {0}; // 从标准输入(键盘)读取一行数据到 buff 数组中,最多读取 128 个字符fgets(buff,128,stdin); // 检查用户输入的内容是否以 "end" 开头,如果是则跳出循环if( strncmp(buff,"end",3) == 0) {break;}// 向服务器地址发送数据,strlen(buff) - 1 是去掉 fgets 读取时包含的换行符sendto(sockfd,buff,strlen(buff)-1,0,(struct sockaddr*)&saddr,sizeof(saddr)); // 将字符数组 buff 的内容清零,为下次接收数据做准备memset(buff,0,128); // 初始化地址结构体长度变量,用于存储从服务器接收数据时地址结构体的长度int len = sizeof(saddr); // 从服务器接收数据,存储到 buff 数组中recvfrom(sockfd,buff,127,0,(struct sockaddr*)&saddr,&len); // 打印接收到的数据printf("buff=%s\n",buff); }// 关闭套接字,释放相关资源close(sockfd); // 正常终止程序exit(0);
}
sendto(sockfd,buff,strlen(buff)-1,0,(struct sockaddr*)&saddr,sizeof(saddr));
- 函数作用:
sendto是用于在 UDP 套接字上发送数据的函数。它可以将数据发送到指定的目标地址。- 参数解释
sockfd:之前创建好的 UDP 套接字描述符,通过它来确定使用哪个套接字发送数据。buff:这是一个字符数组,存储着要发送的数据内容,也就是用户通过fgets从标准输入获取并准备发送给服务器的数据。strlen(buff) - 1:strlen函数用于获取buff中字符串的长度。因为fgets函数读取输入时会把换行符\n也读取到buff数组中,而实际发送数据时通常不需要这个换行符,所以减去 1 来去掉它 。这个值表示实际要发送的数据长度。0:表示发送数据时的标志位,这里设置为 0 表示没有特殊的发送选项。(struct sockaddr*)&saddr:将服务器地址结构体saddr的指针强制转换为通用的sockaddr指针类型,用于指定数据要发送到的目标地址,这里就是服务器的地址。sizeof(saddr):表示目标地址结构体saddr的大小,用于告诉sendto函数地址信息占用的字节数。
recvfrom(sockfd,buff,127,0,(struct sockaddr*)&saddr,&len);
- 函数作用:
recvfrom是用于在 UDP 套接字上接收数据的函数,同时它还能获取发送方的地址信息。- 参数解释
sockfd:UDP 套接字描述符,通过它确定从哪个套接字接收数据。buff:用于存储接收到的数据的字符数组,这里它的大小为 128 ,但实际接收数据时预留 1 个字节用于存储字符串结束符\0,所以指定接收长度为 127 。0:接收数据时的标志位,设置为 0 表示没有特殊接收选项。(struct sockaddr*)&saddr:用于存储发送方(客户端)地址信息的结构体指针,将其强制转换为通用的sockaddr指针类型。在函数执行过程中,它会被填充为实际发送数据的客户端的地址信息。&len:是一个指向表示地址结构体长度变量的指针。recvfrom函数会根据实际接收到的地址信息长度来更新这个变量的值。
2.2 服务端ser.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>int main()
{// 创建一个 UDP 套接字,AF_INET 表示使用 IPv4 地址族,SOCK_DGRAM 表示 UDP 协议int sockfd = socket(AF_INET,SOCK_DGRAM,0); // 检查套接字是否创建成功,若失败(返回 -1)则退出程序if( -1 == sockfd){exit(1);}// 定义两个 IPv4 套接字地址结构体,saddr 用于服务器地址,caddr 用于客户端地址struct sockaddr_in saddr, caddr;// 将服务器地址结构体 saddr 的内存初始化为 0memset(&saddr,0,sizeof(saddr));// 设置地址族为 IPv4saddr.sin_family = AF_INET;// 将端口号 6000 从主机字节序转换为网络字节序saddr.sin_port = htons(6000);// 将 IP 地址 "127.0.0.1" 从点分十进制转换为网络字节序saddr.sin_addr.s_addr = inet_addr("127.0.0.1");// 将套接字 sockfd 绑定到指定的地址(saddr)int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));// 检查绑定操作是否成功,若失败(返回 -1)则打印错误信息if( res == -1){printf("bind err\n");}// 进入无限循环,持续接收和响应客户端消息while( 1 ){// 定义字符数组 buff,用于存储接收到的消息,初始化为 0char buff[128] = {0};// 初始化客户端地址结构体 caddr 的长度int len = sizeof(caddr);// 从客户端接收数据,存储到 buff 中,同时获取客户端地址信息int n = recvfrom(sockfd,buff,128,0,(struct sockaddr*)&caddr,&len);// 打印接收到的消息内容printf("buff=%s\n",buff);// 向客户端发送 "ok" 消息sendto(sockfd,"ok",2,0,(struct sockaddr*)&caddr,sizeof(caddr));}// 关闭套接字,释放资源close(sockfd);// 正常退出程序exit(0);
}
int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));这行代码的作用是将之前创建的套接字
sockfd绑定到由saddr结构体所表示的网络地址上,并通过返回值res来判断绑定操作是否成功。
bind函数是用于在网络编程中把一个套接字(socket)和一个特定的地址绑定在一起的系统函数。在 TCP 或 UDP 服务器程序中,通常使用bind函数将服务器套接字绑定到一个指定的 IP 地址和端口号上,这样服务器就能在该地址上监听并接收来自客户端的连接请求或数据。
相关文章:
UDP概念特点+编程流程
UDP概念编程流程 目录 一、UDP基本概念 1.1 概念 1.2 特点 1.2.1 无连接性: 1.2.2 不可靠性 1.2.3 面向报文 二、UDP编程流程 2.1 客户端 cli.c 2.2 服务端ser.c 一、UDP基本概念 1.1 概念 UDP 即用户数据报协议(User Datagram Protocol &…...
celery rabbitmq 配置 broker和backend
在使用Celery和RabbitMQ作为消息代理和结果后端时,你需要正确配置Celery以便它们可以有效地通信。以下是如何配置Celery以使用RabbitMQ作为broker(消息代理)和backend(结果后端)的步骤: 安装必要的库 首先…...
vue+electron ipc+sql相关开发(三)
在 Electron 中使用 IPC(Inter-Process Communication)与 SQLite 数据库进行通信是一个常见的模式,特别是在需要将数据库操作从渲染进程(Vue.js)移到主进程(Electron)的情况下。这样可以更好地管理数据库连接和提高安全性。下一篇介绍结合axios写成通用接口形式,虽然没…...
[特殊字符] PostgreSQL MCP 开发指南
简介 🚀 PostgreSQL MCP 是一个基于 FastMCP 框架的 PostgreSQL 数据库交互服务。它提供了一套简单易用的工具函数,让你能够通过 API 方式与 PostgreSQL 数据库进行交互。 功能特点 ✨ 🔄 数据库连接管理与重试机制🔍 执行 SQL…...
GD32裸机程序-SFUD接口文件记录
SFUD gitee地址 SFUD spi初始化 /********************************************************************************* file : bsp_spi.c* author : shchl* brief : None* version : 1.0* attention : None* date : 25-…...
Flutter项目之设置页
目录: 1、实现效果图2、实现流程2.1、引入依赖2.2、封装弹窗工具类2.3、设置页2.4、路由中注册设置页面 1、实现效果图 2、实现流程 2.1、引入依赖 2.2、封装弹窗工具类 import package:fluttertoast/fluttertoast.dart;class CommontToast {static showToast(Str…...
【Pandas】pandas DataFrame tail
Pandas2.2 DataFrame Indexing, iteration 方法描述DataFrame.head([n])用于返回 DataFrame 的前几行DataFrame.at快速访问和修改 DataFrame 中单个值的方法DataFrame.iat快速访问和修改 DataFrame 中单个值的方法DataFrame.loc用于基于标签(行标签和列标签&#…...
通过GO后端项目实践理解DDD架构
最近在工作过程中重构的项目要求使用DDD架构,在网上查询资料发现教程五花八门,并且大部分内容都是长篇的概念讲解,晦涩难懂,笔者看了一些github上入门的使用DDD的GO项目,并结合自己开发中的经验,谈谈自己对…...
精益数据分析(2/126):解锁数据驱动的商业成功密码
精益数据分析(2/126):解锁数据驱动的商业成功密码 大家好!在如今这个数据爆炸的时代,数据就像一座蕴含无限宝藏的矿山,等待着我们去挖掘和利用。最近我在深入研读《精益数据分析》这本书,收获了…...
天线静电防护:NRESDTLC5V0D8B
一. 物联网天线的使用环境 1.1 联网天线广泛应用于智能家居领域,比如智能门锁、智能摄像头等设备中,通过天线实现设备与家庭网络的连接,用户可以远程控制和监控家居设备。以智能摄像头为例,它通过天线将拍摄的画面实时传输到用户…...
【Linux 并发与竞争】
【Linux 并发与竞争】 Linux是一个多任务操作系统,肯定会存在多个任务共同操作同一段内存或者设备的情况,多个任务甚至中断都能访问的资源叫做共享资源,就和共享单车一样。在驱动开发中要注意对共享资源的保护,也就是要处理对共享…...
实用类题目
1. 密码强度检测 题目描述:生活中,为保证账户安全,密码需要有一定强度。编写一个方法,接收一个字符串作为密码,判断其是否符合以下强度要求:长度至少为 8 位,包含至少一个大写字母、一个小写字…...
STM32F103C8T6-基于FreeRTOS系统实现步进电机控制
引言 上一篇文章讲述了如何使用蓝牙连接stm32进行数据收发控制步进电机,这篇在之前的基础上通过移植操作系统(FreeRTOS或者其他的也可以,原理操作都类似)实现步进电机控制。 上篇博客指路:STM32蓝牙连接Android实现云…...
macOS安装java
一、下载 官网Java Downloads | Oracle 安装载java8,下载对应的JDK Java Downloads | Oracle 二、双击安装 安装 完成 三、查看安装位置 打开终端窗口,执行命令: /usr/libexec/java_home -V /Library/Java/JavaVirtualMachines/jdk-1.8.jdk/Content…...
ArrayList的subList的数据仍是集合
ArrayList的subList结果不可强转成ArrayList,否则会抛出 ClassCastException异常 • 级别: 【CRITICAL】 • 规约类型:BUG • 最坏影响: 程序错误,抛出异常 说明:subList 返回的是ArrayList的内部类SubL…...
zkmall模块商城:B2C 场景下 Vue3 前端性能优化的广度探索与实践
ZKmall作为面向B2C场景的模块化电商平台,其前端性能优化在Vue3框架下的实践融合了架构设计、渲染机制与业务特性,形成了一套多维度的优化体系。以下从技术实现与业务适配两个维度展开分析: 一、Vue3响应式系统深度适配 Proxy驱动的精准更新…...
【Netty篇】Future Promise 详解
目录 一、 Netty Future 与 Promise —— 异步世界的“信使”与“传话筒”🚀1、 理解 Netty Future2、 理解 Netty Promise 二、 代码案例解读💻例1:同步处理任务成功👍例2:异步处理任务成功📲例3ÿ…...
第3.3节:print函数详解
1 第3.3节:print函数详解 print是AWK中最常用的输出函数,它可以将指定的变量、字段或表达式的值输出到标准输出。以下是其详细用法: 1.1 基本语法 print (expr1), (expr2), ..., (exprN)。其中expr1, expr2, ..., exprN是要输出的表达式&a…...
视频分析设备平台EasyCVR安防视频管理系统,打造电石生产智能视频监控新体系
一、背景介绍 电石生产中的出炉工序是整个生产流程中最为繁重且危险的环节。在开堵炉眼的过程中,电石极易发生飞溅现象,尤其在进行吹氧操作时,人员灼伤的风险极高。鉴于此,该工序正逐步由传统的人工操作模式向智能化方向转变。然…...
C语言中的.操作符与->操作符的区别
.操作符->操作符访问方式成员访问操作符(类,结构体的成员)指针来访问对象的成员语法形式对象.成员指针->成员举例 person是结构体的对象,里面有一个age是成员变量 person.age 例如,如果有一个指向 person 结构体…...
从 PyTorch 到 ONNX:深度学习模型导出全解析
在模型训练完毕后,我们通常希望将其部署到推理平台中,比如 TensorRT、ONNX Runtime 或移动端框架。而 ONNX(Open Neural Network Exchange)正是 PyTorch 与这些平台之间的桥梁。 本文将以一个图像去噪模型 SimpleDenoiser 为例&a…...
Android 应用添加Tile到SystemUI QuickSettings
安卓源码里有谷歌给的关于 Tile 的说明。 frameworks/base/packages/SystemUI/docs/qs-tiles.md SystemUI QuickSettings 简称QS,指的是 下拉菜单里的区域。区域里的一个选项就是一个 Tile 。 下图是 frameworks/base/packages/SystemUI/docs/ 里的附图示例&#…...
【MySQL】前缀索引、索引下推、访问方法,自适应哈希索引
最左前缀原则 对于INDEX(name, age)来说最左前缀可以是联合索引的最左N个字段, 也可以是字符串索引的最左M个字符。 SELECT * FROM t WHERE name LIKE 张%其效果和单独创建一个INDEX(name)的效果是一样的若通过调整索引字段的顺序, 可以少维护一个索引树, 那么这个顺序就是需要…...
C++中变量、函数存储、包括虚函数多态实现机制说明
从C语言转到C开发,对于类内变量的存储,类内函数的存储,存在疑惑; 子类如何继承父类的变量的?如果子类和父类变量同名了怎么办?C中,函数有了作用域,类内函数,只能是这个类或对应对…...
Android Studio开发知识:从基础到进阶
引言 Android开发作为移动应用开发的主流方向之一,曾吸引了无数开发者投身其中。然而,随着市场饱和和技术迭代,当前的Android开发就业形势并不乐观,竞争日益激烈。尽管如此,掌握扎实的开发技能仍然是脱颖而出的关键。本…...
数据加载与保存
通用方式 SparkSQL提供了通用的数据加载方式,使用spark.read.loa方法,并可通过format指定数据类型(如csv、jdbc、json、orc、parquet、textFile)。 load方法后需传入数据路径(针对csv、jdbc、json、orc、parquet、…...
linux命令九
系统服务 常见重点配置 Listen:监听地址:端口(80) ServerName:本站点注册的DNS名称(空缺) DocumentRoot:网页根目录(/var/www/html) DirectoryIndex:起始…...
ocr-身份证正反面识别
在阿里云官网,申请一个token [阿里官方]身份证OCR文字识别_API专区_云市场-阿里云 (aliyun.com) 观察一下post请求body部分json字符串,我们根据这个创建一个java对象 先默认是人像面 public class IdentityBody {public String image;class configure…...
PCIE Link Equalizaton
1. 均衡概述 link均衡是用于通过调整tx rx的参数来提高信号质量, 所有有LTSSM关联的lane都需要进行均衡操作。均衡只有在低速率的均衡完成之后才可以进行后续高速度的均衡,虽然协议规定可以重复做均衡,但是还是不建议进行同意速率的重复多次均…...
单节锂电池4.2V升压5V都有哪些国产芯片推荐?国产SL4011高效,高性价比
针对单节锂电池(4.2V)升压至5V应用中 SL4011升压芯片 的核心优势解析,结合其技术参数与典型应用场景进行详细说明: 1. 宽输入电压与高兼容性 输入范围:2.7V-12V,完美覆盖单节锂电池全周期电压(3…...
