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

【计算机网络】传输层UDP协议

🔥个人主页🔥:孤寂大仙V
🌈收录专栏🌈:计算机网络
🌹往期回顾🌹: 【计算机网络】应用层协议Http——构建Http服务服务器
🔖流水不争,争的是滔滔不息


  • 一、UDP协议
  • 二、UDP特点
    • 面向数据报
  • 三、UDP缓冲区
  • 四、基于UDP的应用层协议
  • 五、报文理解

一、UDP协议

UDP(User Datagram Protocol,用户数据报协议)是一种无连接的传输层协议,提供简单的、不可靠的数据传输服务。与TCP不同,UDP不保证数据包的顺序、可靠性或流量控制,但具有低延迟和高效率的特点,适用于实时性要求高但允许少量丢包的应用场景。

UDP协议端格式
在这里插入图片描述
UDP 报文其实很简单,它的格式是 “定长报头 + 不定长数据”。如图上面8字节是报头大小,下面数据是有效载荷。UDP报头是定长报头,所以每个报文交付给上层报头都是确定的。UDP报文分离的时候,直接把定长的报头和有效载荷分离就好了,分用根据目的端口号去完成。UDP报文和报文之间都有有边界的,所以不用像TCP传输那样还要自定义协议区区分报头。16位源端口号是表示报文是从哪发的,16位目的端口号是表示报文要发到哪里。端口号设计为16位的,是因为内核协议是16位的。报头是固定的,每个报文的有效载荷能和报头分明的区分,且报文和报文之间有边界,这就是用户数据报最大的特点。16 位 UDP 长度, 表示整个数据报(UDP 首部+UDP 数据)的最大长度;如果校验和出错, 就会直接丢弃;

为什么说UDP简单?
UDP和TCP有一个最大的不同:UDP是有“边界”的协议,每一个UDP报文本身就是独立的一块
内核收到一个UDP报文,直接把8字节头部剥掉,剩下的数据送到应用层就行。
每一个recvfrom()调用,只会收到一个完整的UDP报文(不会拆开,也不会合并)。
不像TCP:TCP是“流”,没有边界,一个包可能拆成多个recv才收完,或者多个包粘在一起。所以TCP应用层必须“自己想办法分包”,比如用自定义协议。

二、UDP特点

UDP 传输的过程类似于寄信。

  • 无连接: 知道对端的 IP 和端口号就直接进行传输, 不需要建立连接;
  • 不可靠: 没有确认机制, 没有重传机制; 如果因为网络故障该段无法发到对方,UDP 协议层也不会给应用层返回任何错误信息;
  • 面向数据报: 不能够灵活的控制读写数据的次数和数量;

面向数据报

应用层交给 UDP 多长的报文, UDP 原样发送, 既不会拆分, 也不会合并;
用 UDP 传输 100 个字节的数据:如果发送端调用一次 sendto, 发送 100 个字节, 那么接收端也必须调用对应的一次 recvfrom, 接收 100 个字节; 而不能循环调用 10 次 recvfrom, 每次接收 10 个字节。

三、UDP缓冲区

在这里插入图片描述
UDP 没有真正意义上的 发送缓冲区. 调用 sendto 会直接交给内核, 由内核将数据传给网络层协议进行后续的传输动作;
UDP 具有接收缓冲区. 但是这个接收缓冲区不能保证收到的 UDP 报的顺序和发送 UDP 报的顺序一致; 如果缓冲区满了, 再到达的 UDP 数据就会被丢弃;
UDP 的 socket 既能读, 也能写, 这个概念叫做 全双工

因为UDP没有发送缓冲区,所以如果报文在网络传输的过程中丢包了,UDP 本身是“无连接 + 不可靠传输协议”,它不会确认你发出去了没,也不会重传,如果在网络中丢了,那就真的丢了,服务器一无所知。

如果应用层正在进行报文的解析,不会影响OS从网络中读取报文

UDP使用注意事项
我们注意到, UDP 协议首部中有一个 16 位的最大长度. 也就是说一个 UDP 能传输的数据最大长度是 64K(包含 UDP 首部).。
然而 64K 在当今的互联网环境下, 是一个非常小的数字,如果我们需要传输的数据超过 64K, 就需要在应用层手动的分包, 多次发送, 并在接收端手动拼装。

四、基于UDP的应用层协议

  • DNS(Domain Name System)
    DNS用于将域名解析为IP地址。由于查询通常只需一次请求-响应,UDP的轻量特性使其成为首选。默认使用端口53。
  • DHCP(Dynamic Host Configuration Protocol)
    DHCP用于自动分配IP地址。UDP的广播和多播支持使其适合局域网内的地址分配。客户端使用端口68,服务器使用端口67。
  • SNMP(Simple Network Management Protocol)
    SNMP用于网络设备监控和管理。UDP的简单性适合频繁的监控数据交换。默认使用端口161(查询)和162(陷阱)。
  • TFTP(Trivial File Transfer Protocol)
    TFTP是简单的文件传输协议,常用于网络引导或设备固件更新。使用UDP端口69,实现比FTP更轻量。
  • QUIC(Quick UDP Internet Connections)
    QUIC是Google开发的传输协议,基于UDP实现类似TCP的可靠性,但减少握手延迟。HTTP/3基于QUIC,提升Web性能。
  • VoIP(Voice over IP)
    语音通话协议如RTP(Real-time Transport Protocol)通常基于UDP。实时性要求高,少量丢包对语音质量影响较小。

五、报文理解

Linux sk_buff源码

struct sk_buff {union {struct {struct sk_buff *next;struct sk_buff *prev;union {struct net_device *dev;unsigned long dev_scratch;};};struct rb_node rbnode; // 用于红黑树};union {struct sock *sk;int ip_defrag_offset;};char cb[48]; // 控制缓冲区,协议层私有数据unsigned long _skb_refdst;unsigned int len, data_len;__u16 mac_len, hdr_len;__u16 queue_mapping;__u8 cloned:1, nohdr:1, fclone:2, peeked:1, head_frag:1;__u8 pfmemalloc:1, pp_recycle:1;__u16 tc_index; // 流量控制索引__u16 transport_header;__u16 network_header;__u16 mac_header;__u32 headers_end[0];void (*destructor)(struct sk_buff *skb);struct nf_conntrack *nfct;unsigned long nfct_reasm;__u32 secmark;unsigned int mark;__u16 vlan_proto;__u16 vlan_tci;union {__u32 inner_network_header;__u32 inner_network_header_offset;};__u32 inner_transport_header;__be16 protocol;__u16 transport_header_was;__u8 encapsulation:1;// 更多字段...unsigned char *head, *data, *tail, *end;
};

在这里插入图片描述
在操作系统内部,可能会同时存在大量的报文,操作系统必须管理这些报文。引入sk_buff(Socket Buffer)是 Linux 内核网络协议栈中 收发数据的核心结构体,每当有网络数据要处理,内核就会分配一个 sk_buff。

skb->head, skb->data, skb->tail, skb->end 是sk_buff内的指针。

  • skb->head:指向整个缓冲区的起始位置(分配的整块内存)
  • skb->data:指向有效数据的起始位置(比如 IP 头部开始)
  • skb->tail:指向有效数据的结尾(可以向后追加数据)
  • skb->end:指向缓冲区结尾(表示最多能写到哪)

所谓封装和解包,本质就是移动data指针在缓冲区中指向。

我们把data和tail想成一个"动态窗口",当我们的报完往下层协议封装就要往前移动data指针,封装报头,当往后移动tail指针的时候是添加新的数据。


发送过程:从上层到下层
调用send()或者write()发送数据,数据经历了用户态->内核态->网络层多次加工封装。
发送数据,数据进入内核socket buffer,内核分配sk_buff,并把数据填进去(通常从skb->tail开始)。进去TCP层,加上TCP报头skb->tail往前移动数据跟在TCP头后面,设置TCP序号、校验和等。进入IP层。加上IP层报头,设置源IP、目的IP等。进入数据链路层加MAC头,设置目标MAC、源MAC等。最后整个数据包都集中在skb->data和skb->tail之间->DMA拷贝给网卡发送过去。
接收过程:从底层到上层
网卡收到数据,触发中断。驱动将数据拷贝到sk_buff。skb->data指向以太网头部。一层一层"剥皮"去掉报头。最后skb->data指向payload(应用层数据)上交给socket buffer,再wake up用户进程接收。

sk_buff 就是内核网络协议栈用来“托运数据”的容器,skb->data 是快递包裹的“当前开箱点”,从 TCP 到 IP 到 MAC,每一层往前预留一段头,然后下发出去。

相关文章:

【计算机网络】传输层UDP协议

🔥个人主页🔥:孤寂大仙V 🌈收录专栏🌈:计算机网络 🌹往期回顾🌹: 【计算机网络】应用层协议Http——构建Http服务服务器 🔖流水不争,争的是滔滔不…...

安全漏洞修复导致SpringBoot2.7与Springfox不兼容

项目基于 springboot2.5.2 实现的&#xff0c;用 springfox-swagger2 生成与前端对接的 API 文档&#xff1b;pom.xml 中依赖如下 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId>&l…...

从法律层面剖析危化品证书:两证一证背后的安全逻辑

《安全生产法》第 24 条明确规定&#xff0c;危化品单位主要负责人和安全管理人员 “必须考核合格方可上岗”。这并非仅仅是行政要求&#xff0c;而是通过法律来筑牢安全防线。在某危化品仓库爆炸事故中&#xff0c;由于负责人未持证&#xff0c;导致事故责任升级&#xff0c;企…...

C语言——获取变量所在地址(uint8和uint32的区别)

前言&#xff1a; 1.使用uint8 *的原因 在C语言中&#xff0c;获取或操作一个4字节地址&#xff08;指针&#xff09;时使用uint8_t*&#xff08;即unsigned char*&#xff09;而不是uint32_t*&#xff0c;主要基于以下关键原因&#xff1a; 1.1. 避免违反严格别名规则&…...

2 Studying《Effective STL》

目录 0 引言 1 容器 1. 慎重选择容器类型 3. 确保容器中的对象副本正确且高效 4. 调用empty()而不是检查size()是否为0 5. 区间成员函数优先于与之对应的单元素成员函数 7. 如果容器中包含了通过new创建的指针&#xff0c;切记析构前将指针delete掉 9. 慎重选择删除元素…...

深入理解复数加法与乘法:MATLAB演示

在学习复数的过程中&#xff0c;复数加法与乘法是两个非常基础且重要的概念。复数的加法和乘法操作与我们常见的实数运算有所不同&#xff0c;它们不仅涉及到数值的大小&#xff0c;还有方向和相位的变化。在这篇博客中&#xff0c;我们将通过MATLAB演示来帮助大家更好地理解复…...

【设计模式-3.6】结构型——桥接模式

说明&#xff1a;本文介绍结构型设计模式之一的桥接模式 定义 桥接模式&#xff08;Bridge Pattern&#xff09;又叫作桥梁模式、接口&#xff08;Interface&#xff09;模式或柄体&#xff08;Handle and Body&#xff09;模式&#xff0c;指将抽象部分与具体实现部分分离&a…...

【前端】性能优化篇

长期更新&#xff0c;建议关注收藏点赞。 目录 性能优化具体指标监控工具/系统解决方案htmlcssjsvuereact包体积静态资源图片优化白屏首屏加载速度缓存优化网络优化web worker动画 面试题汇总怎么实现无限加载&#xff0c;如果有一亿条数据怎么优化 性能优化 本文仅是列出常见…...

【redis实战篇】第六天

摘要&#xff1a; 本文介绍了基于Redis的秒杀系统优化方案&#xff0c;主要包含两部分&#xff1a;1&#xff09;通过Lua脚本校验用户秒杀资格&#xff0c;结合Java异步处理订单提升性能&#xff1b;2&#xff09;使用Redis Stream实现消息队列处理订单。方案采用Lua脚本保证库…...

力扣题解654:最大二叉树

一、题目内容 题目要求根据一个不重复的整数数组 nums 构建最大二叉树。最大二叉树的构建规则如下&#xff1a; 创建一个根节点&#xff0c;其值为 nums 中的最大值。递归地在最大值左边的子数组前缀上构建左子树。递归地在最大值右边的子数组后缀上构建右子树。返回由 nums 构…...

手写ArrayList和LinkedList

项目仓库&#xff1a;https://gitee.com/bossDuy/hand-tear-collection-series 基于b站up生生大佬&#xff1a;https://www.bilibili.com/video/BV1Kp5tzGEc5/?spm_id_from333.788.videopod.sections&vd_source4cda4baec795c32b16ddd661bb9ce865 LinkedList package com…...

Android bindservice绑定服务,bindServiceAsUser补充

Android bindservice绑定服务&#xff0c;并同步返回service对象的两个方法-CSDN博客 补充反射并调用bindServiceAsUser的方法&#xff1a; private boolean initService2(final Context context){if(deviceServicenull){latch new CountDownLatch(1);HandlerThread handler…...

[蓝桥杯]交换次数

交换次数 题目描述 IT 产业人才需求节节攀升。业内巨头百度、阿里巴巴、腾讯&#xff08;简称 BAT &#xff09;在某海滩进行招聘活动。 招聘部门一字排开。由于是自由抢占席位&#xff0c;三大公司的席位随机交错在一起&#xff0c;形如&#xff1a;BABTATT&#xff0c;这使…...

95套HTML高端大数据可视化大屏源码分享

概述​​ 在大数据时代&#xff0c;数据可视化已成为各行各业的重要需求。这里精心整理了95套高端HTML大数据可视化大屏源码&#xff0c;这些资源采用现代化设计风格&#xff0c;可帮助开发者快速构建专业的数据展示界面。 ​​主要内容​​ ​​1. 设计风格与特点​​ 采用…...

系统架构设计综合知识与案例分析

system-architect 软考高级-系统架构设计师-综合知识与案例分析&#xff1a;软件工程、网络工程、结构化分析方法、面向对象分析方法、软件质量数量、传统数据库、分布式数据库、系统架构等。 —— 2025 年 3 月 20 日 甲辰年二月二十一 春分 目录 system-architect1、计算机基…...

scale up 不能优化 TCP 聚合性能

scale up 作为一种系统扩展优化的方法&#xff0c;旨在提高系统组件的执行效率&#xff0c;比如替换更高性能的硬件或算法。是否可以此为依据优化 TCP 呢&#xff0c;例如通过多条路径聚合带宽实现吞吐优化(对&#xff0c;还是那个 MPTCP)&#xff0c;答案是否定的。 因为 TCP…...

Python-matplotlib库之核心对象

matplotlib库之核心对象 FigureFigure作用Figure常用属性Figure常用方法Figure对象的创建隐式创建&#xff08;通过 pyplot&#xff09;显式创建使用subplots()一次性创建 Figure 和 Axes Axes&#xff08;绘图区&#xff09;Axes创建方式Axes基本绘图功能Axes绘图的常用参数Ax…...

Linux 脚本文件编辑(vim)

1. 用户级配置文件&#xff08;~/.bashrc&#xff09; vim ~/.bashrc # 编辑 source ~/.bashrc # 让编辑生效 ~/.bashrc 文件是 Bash Shell 的配置文件&#xff0c;用于定义用户登录时的环境变量、别名、函数等设置。当你修改了 ~/.bashrc 文件后&#xff0c;通常需要重新…...

学习BI---基本操作---数据集操作

什么是数据集&#xff0c; 数据集&#xff08;Dataset&#xff09;​​ 是指从原始数据源&#xff08;如数据库、Excel、API等&#xff09;提取并经过标准化处理后的数据集合&#xff0c;通常以二维表形式存储&#xff0c;用于支撑报表、仪表盘等可视化分析。 数据集在QuickB…...

初学大模型部署以及案例应用(windows+wsl+dify+mysql+Ollama+Xinference)

大模型部署以及案例应用&#xff08;windowswsldifymysqlOllamaXinference&#xff09; 1.wsl 安装①安装wsl②测试以及更新③安装Ubuntu系统查看系统以及版本安装Ubuntu系统进入Ubuntu系统 2、docker安装①下载安装包②安装③docker配置 3、安装dify①下载dify②安装③生成.en…...

AI Agent企业级生产应用全解析

在企业级应用中&#xff0c;AI Agent 的核心是将其从一个对话模型转变为一个自主决策和执行的自动化工作流引擎。这需要一个精密的 “Agent 执行框架”&#xff08;Agent Orchestration Framework&#xff09; 来协调 LLM 的推理、外部工具的调用、记忆管理和自我反思。 AI Ag…...

RocketMQ 学习

消息队列 参考官方文档&#xff1a;https://rocketmq.apache.org/zh/docs/ 基本概念 主题&#xff08;Topic&#xff09;&#xff1a;是消息传输和消息存储的顶级容器&#xff0c;不是实际的消息容器&#xff0c;而是一个逻辑上的概念&#xff0c;用于区分不同业务消息的标识&…...

【前端】html2pdf实现用前端下载pdf

npm安装完后&#xff0c;编写代码。 <template><div id"pdf-content">需要被捕获为pdf的内容</div> </template><script> import html2pdf from html2pdf.js;export default {methods: {downloadPdf() {const element document.getE…...

Redis部署架构详解:原理、场景与最佳实践

Redis部署架构详解&#xff1a;原理、场景与最佳实践 Redis作为一种高性能的内存数据库&#xff0c;在现代应用架构中扮演着至关重要的角色。随着业务规模的扩大和系统复杂度的提升&#xff0c;选择合适的Redis部署架构变得尤为重要。本文将详细介绍Redis的各种部署架构模式&a…...

前端开发知识体系全景指南

文章目录 前言前端开发者知识体系清单一、JavaScript基础变量和类型原型和原型链作用域和闭包执行机制语法和API 二、HTML和CSSHTMLCSS手写 三、计算机基础编译原理网络协议设计模式 四、数据结构和算法JavaScript编码能力手动实现前端轮子数据结构算法 五、运行环境浏览器API浏…...

C++哈希表:unordered系列容器详解

本节目标 1.unordered系列关联式容器 2.底层结构 3.模拟实现 4.哈希的应用 5.海量数据处理面试题 unordered系列关联式容器 在c98中&#xff0c;STL提供了底层为红黑树结构的一系列关联式容器&#xff0c;在查询时效率可以达到logN&#xff0c;即最差的情况下需要比较红…...

vue-13(延迟加载路由)

用于性能优化的延迟加载路由 延迟加载路由是优化 Vue.js 应用程序性能的关键技术&#xff0c;尤其是那些具有大量路由的应用程序。通过仅在实际需要时加载路由组件&#xff0c;您可以显著减少应用程序的初始加载时间&#xff0c;从而获得更好的用户体验。这对于网络连接速度较…...

pom.xml 文件中配置你项目中的外部 jar 包打包方式

使用 system 作用域&#xff08;不推荐&#xff0c;但简单直接&#xff09; <dependency><groupId>com.test</groupId> <!-- 可自定义&#xff0c;建议与项目相关 --><artifactId>open-sdk</artifactId> <!-- 可自定义&#xff0c;建议…...

WordPress通过简码插入bilibili视频

发布于&#xff1a;Eucalyptus-Blog 一、前言 B站是国内非常受欢迎的视频分享平台&#xff0c;上面不仅内容丰富&#xff0c;而且很多视频制作精良、趣味十足。很多人&#xff0c;比如我&#xff0c;就喜欢将B站的视频通过 iframe 嵌入到自己的网页中&#xff0c;但这段代码又…...

ZLG ZCANPro,ECU刷新,bug分享

文章目录 摘要 📋问题的起因bug分享 ✨思考&反思 🤔摘要 📋 ZCANPro想必大家都不陌生,买ZLG的CAN卡,必须要用的上位机软件。在汽车行业中,有ECU软件升级的需求,通常都通过UDS协议实现程序的更新,满足UDS升级的上位机要么自己开发,要么用CANoe或者VFlash,最近…...