【计算机网络】传输层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,每一层往前预留一段头,然后下发出去。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/85761.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

「Java教案」顺序结构

课程目标 1.知识目标 能够正确使用Java顺序结构的基本语法,例如变量的声明、变量的赋值、表达式的计算、数据的输出。能够正确使用顺序结构的执行规则及其在程序中的作用,解决实际问题。 2.能力目标 能够独立完成顺序结构程序…

第八部分:阶段项目 6:构建 React 前端应用

现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…

GO语言----基础类型取别名

文章目录 取别名示例注意事项 Go语言中使用type关键字为基础类型取别名。 type是Go语言中用于定义新类型的关键字,它提供了强大的类型定义能力。 取别名示例 type MyInt int注意事项 这创建了一个新类型MyInt,它底层是int类型,但与int是不同…

服务端定时器的学习(一)

一、定时器 1、定时器是什么? 定时器不仅存在于硬件领域,在软件层面(客户端、网页和服务端)也普遍应用,核心功能都是高效管理大量延时任务。不同应用场景下,其实现方式和使用方法有所差异。 2、定时器解…

Mac版本Android Studio配置LeetCode插件

第一步:Android Studio里面找到Settings,找到Plugins,在Marketplace里面搜索LeetCode Editor。 第二步:安装对应插件,并在Tools->LeetCode Plugin页面输入帐号和密码。 理论上,应该就可以使用了。但是&a…

【ISP算法精粹】动手实战:用 Python 实现 Bayer 图像的黑电平校正

在数字成像领域,图像信号处理器(ISP)如同幕后英雄,默默将传感器捕获的原始数据转化为精美的图像。而黑电平校正,作为ISP预处理流程中的关键一环,直接影响着最终图像的质量。今天,我们就通过Pyth…

Oracle OCP与MySQL OCP认证如何选?

认证本质与定位差异 Oracle OCP Oracle OCP是Oracle公司推出的旗舰级数据库专家认证,专注于其核心的闭源商业数据库技术体系。核心领域包括RAC(Real Application Clusters)高可用集群、Data Guard容灾解决方案、Exadata数据库一体机集成以及…

MVVM、MVC的区别、什么是MVVM

一、什么是MVVM (一)定义 MVVM是Model - View - ViewModel的缩写,它是一种软件架构设计模式,主要用于构建用户界面。这种模式将应用程序分为三个主要部分: Model(模型层) 它是应用程序中负责…

【SpringCache 提供的一套基于注解的缓存抽象机制】

Spring 缓存(Spring Cache)是 Spring 提供的一套基于注解的缓存抽象机制,常用于提升系统性能、减少重复查询数据库或接口调用。 ✅ 一、基本原理 Spring Cache 通过对方法的返回结果进行缓存,后续相同参数的调用将直接从缓存中读…

HRI-2025 | 大模型驱动的个性化可解释机器人人机交互研究

作者:Ferran Gebelli 1 ^{1} 1, Lavinia Hriscu 2 ^{2} 2, Raquel Ros 1 ^{1} 1, Sverin Lemaignan 1 ^{1} 1, Alberto Sanfeliu 2 ^{2} 2, Anais Garrell 2 ^{2} 2单位: 1 ^{1} 1PAL Robotics, 2 ^{2} 2IRI (UPC-CSIC)论文标题:P…

Gitee Wiki:重塑关键领域软件研发的知识管理范式

在数字化转型浪潮席卷全球的当下,关键领域软件研发正面临前所未有的知识管理挑战。传统文档管理模式的局限性日益凸显,知识传承的断层问题愈发严重,团队协作效率的瓶颈亟待突破。Gitee Wiki作为新一代知识管理平台,正在通过技术创…

JVM 内存溢出 详解

内存溢出 内存溢出指的是内存中某一块区域的使用量超过了允许使用的最大值,从而使用内存时因空间不足而失败,虚拟机一般会抛出指定的错误。 在Java虚拟机中,只有程序计数器不会出现内存溢出的情况,因为每个线程的程序计数器只保…

dvwa8——SQL Injection(Blind)

由题目得这一关用盲注写 LOW: 先用bp抓包一下 , 看到这low是get提交 , f12打开hackbar 输入?id1时报错 尝试闭合 , 回显正常 开始注入 1.order by 判断列数,3的时候开始回显报错,所以有两列 ?id1 order by 2--&SubmitSubmit# 2.无回显位置可以爆出,我们通过盲注来继…

探索分布式存储与通信:去中心化共享及通訊(DSAC)

在当今数字化时代,分布式系统的重要性愈发凸显。它不仅能提升数据的存储安全性和可靠性,还能增强通信的效率和隐私性。于是我做了这个去中心化共享及通訊的程序,它构建了一个强大的分布式存储和通信网络,下面我们就来详细了解其实…

ass字幕嵌入mp4带偏移

# 格式转化文件,包含多种文件的互相转化,主要与视频相关 from pathlib import Path import subprocess import random import os import reclass Utils(object):staticmethoddef get_decimal_part(x: float) -> float:s format(x, .15f) # 格式化为…

05 APP 自动化- Appium 单点触控 多点触控

文章目录 一、单点触控查看指针的指针位置实现手势密码: 二、多点触控 一、单点触控 查看指针的指针位置 方便查看手势密码-九宫格每个点的坐标 实现手势密码: 执行手势操作: 按压起点 -> 移动到下一点 -> 依次移动 -> 释放&am…

【软件】在 macOS 上安装 MySQL

在 macOS 上安装 MySQL 有多种方法,以下是两种常见的安装方式:通过 Homebrew 安装和通过安装包安装。以下是详细的步骤: 一、通过 Homebrew 安装 MySQL Homebrew 是 macOS 的包管理器,使用它安装 MySQL 非常方便。 1.安装 Home…

第11节 Node.js 模块系统

为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块系统。 模块是Node.js 应用程序的基本组成部分,文件和模块是一一对应的。换言之,一个 Node.js 文件就是一个模块,这个文件可能是JavaScript 代码、JSON 或者编译过的…

力扣热题100之二叉树的直径

题目 给你一棵二叉树的根节点,返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们之间边数表示。 代码 方法:递归 计算二叉树的直径可以理解…

OpenCV CUDA模块图像处理------创建CUDA加速的Canny边缘检测器对象createCannyEdgeDetector()

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 该函数用于创建一个 CUDA 加速的 Canny 边缘检测器对象(CannyEdgeDetector),可以在 GPU 上高效执行 Canny 边…