为什么 UDP 头只有 8 个字节

2023-05-16

为什么这么设计(Why’s THE Design)是一系列关于计算机领域中程序设计决策的文章,我们在这个系列的每一篇文章中都会提出一个具体的问题并从不同的角度讨论这种设计的优缺点、对具体实现造成的影响。如果你有想要了解的问题,可以在文章下面留言。

​UDP 与 TCP 两种传输协议是 IP 协议簇的核心成员,1980 年发布的 RFC 768 定义了 UDP 协议,我们可以通过它在多个计算机连接构成的网络中传递数据。常见的 DNS 协议就可以使用 UDP 协议获取域名解析的结果,我们在这一系列前面的 为什么 DNS 使用 UDP 协议 中曾经讨论过 DNS 使用的传输协议。

UDP 是能够传输数据的最简单的协议,它的协议首部(也称作协议头)只有 8 个字节,很多人,尤其是应届毕业生都能通过死机硬背暂时记住 UDP 协议头包含的内容,但是知道协议头的内容不代表我们真正理解背后的原因。本文会分析为什么只有 8 个字节的 UDP 协议能够传输数据,相信这篇文章能帮助你更好地理解 UDP 协议头中字段的作用。

 图 1 - UDP 协议头

UDP 协议头中只包含 4 个字段,分别是源端口、目的端口、长度和校验码,其中每一个字段都占 16 比特,即 2 字节,这 4 个字段的作用如下:

  • 源端口是一个可选字段,它表示发送方进程的端口号,接收方可以使用该字段(不一定准确)向发送方发送信息;
  • 目的端口是数据报接收方的端口号,它只在目标的 IP 地址下才有意义;
  • 长度是协议头和数据报中数据长度的总和,表示整个数据报的大小;
  • 校验码使用 IP 首部、UDP 首部和数据报中的数据进行计算,接收方可以通过校验码验证数据的准确性,发现传输过程中出现的问题;

通过 Wireshark 抓包来查看实际使用中 UDP 协议首部的值。当我们执行 dig baidu.com 命令时,本地就会向 DNS 服务器发送 DNS 查询,下面就是一个 DNS 查询中 UDP 首部的例子:

0000   ff 7c 00 35 00 23 c2 6e

上述 UDP 首部中四个字段对应的值如下:

字段数据
源端口0xff7c = 65404
目的端口0x0035 = 53
长度0x0023 = 35
校验码0xc26e

由于 DNS 协议使用的端口是 53,所以上述 UDP 首部中的目的端口就是 53。源端口就是本地发出 DNS 请求的端口,该端口也用来接收 DNS 响应。

定义 UDP 协议的 RFC 768 文档只有 3 页,由于 UDP 协议既不需要保证送达,也不需要保证顺序,所以它没有 TCP 协议那么复杂。TCP 协议中的三次握手、拥塞控制算法和重传策略等机制都是为了提供可靠性所付出的必要代价,但是 UDP 协议不需要这些策略,它只尽力保证数据报的送达。

我们今天来分析一下为什么首部只有 8 个字节的 UDP 协议能够将数据传输到目的地并由特定的服务接收和处理。我们可以将应用到应用之间的传输过程分成两个部分:主机到主机的数据传输和主机到应用的数据转发。

  • UDP 协议底层的网际协议(Internet Protocol,IP)会负责数据包在主机之间的传输;
  • UDP 协议首部的端口号用于定位处理数据的具体进程并转发数据;

我们都说 UDP 协议是传输层协议,但是真正在主机间完成『数据传输』工作的是 IP 协议,UDP 协议只起到了定位具体进程的作用。

数据传输

RFC768 在介绍 UDP 协议时强调 UDP 协议假设底层会使用 IP 协议。IP 协议是 TCP/IP 协议栈的核心成员,它不保证端到端数据的可靠性和顺序,也不包含流控制等机制,其作用就是从来源向目的地传输数据包6。在本文中,我们只需要知道 IP 协议头中包含源 IP 和目的 IP,就不展开介绍 IP 协议的具体实现了,感兴趣的读者可以阅读 RFC791 和相关文档了解更多的内容。

『UDP 协议只能尽力送达数据』这一说法『继承』自 UDP 的下层协议,也就是 IP 协议。只包含了两个端口号的 UDP 协议本身是无法提供路由和寻址功能的,它还是需要下层的协议来解决这个问题。

上面提到的这种各司其职的设计源于网络通讯协议的分层结构。抽象是计算机科学中的基础概念,通过定义良好的接口、构建抽象层,我们可以减少同时需要关注的问题,让每一层都能聚焦到需要处理的问题上。TCP/IP 协议簇将通信过程分成了四个抽象层,分别是:链接层(Link)、网络层(Internet)、传输层(Transport)和应用层(Application)。

图 2 - TCP/IP 协议簇的抽象层

不同的抽象层有着完全不同的功能,我们来看一下网络层和传输层的职责。TCP 和 UDP 等传输层协议的主要作用是为应用建立基本的数据管道,为特定任务提供数据传输的功能;而 IP 等网络层协议的主要作用是寻址和路由,它能够帮助我们将数据发送目标的主机。

简单总结一下,UDP 协议下层的 IP 协议实现数据包的传输,虽然 UDP 属于传输层协议,但是其本身没有提供主机到主机的数据传输能力。

进程定位

在软件层面上,端口是用来表示特定进程或者特定类型网络服务的逻辑概念,计算机硬件中也有端口的概念,但是这里说的端口是没有实体的。当主机接收到 IP 数据包时会根据协议号交给不同的模块处理,TCP 和 UDP 协议会根据端口号确定送给对应的进程处理。

虽然 TCP 和 UDP 协议中都有端口号这一概念,但是因为它们两者的端口不在一个命名空间下(TCP 和 UDP 是两套命名空间),所以 TCP 和 UDP 可以同时使用相同的端口号,例如:53/TCP 和 53/UDP,这两个端口号后的服务都处理 DNS 请求。从这一点来看,只有通过 IP 地址、传输层协议和端口号三者才能在网络上定位到具体的服务,只凭借 IP 地址和端口号是不可行的。

图 3 - TCP 和 UDP 的重复端口号

UDP 协议中的两个端口号占据了 UDP 协议头的一半开销,这从侧面表明了端口号在 UDP 协议的重要地位和 UDP 协议的主要功能。接收 IP 数据包的主机可以使用目的端口号找到特定的进程,该进程也可以使用数据包中的源端口号向发送方回复数据。

 图 4 - 端口号和进程

TCP 和 UDP 的端口号是主机和进程的中间层,进程和端口号既可以是一对一的关系,也可以是一对多的关系,端口号的引入可以让同一个主机上的多个进程对外提供服务,也可以让一个进程对外提供多个服务。有了端口号,想要访问主机服务的请求也不需要使用进程标识符等方式定位提供服务的具体进程。

总结

简单回答一下本文提出的问题:UDP 协议利用下层的 IP 协议提供基本的数据传输能力,它的作用就是引入端口号的概念让同一主机可以同时提供对外多个服务,由于不保证可靠性,所以协议本身只占用 8 个字节。

在理想情况下,我们可以在 IP 协议上构建新的传输层协议实现特定的需求,不过在实际操作中由于协议号的限制,新的传输层协议无法被大量部署的网络地址转换(Network address translation,NAT)设备识别和支持,所以使用这种方式构建新的传输层协议在实践中难以落实。

注1:协议号是 IP 首部中的一个字段,它表示当前报文数据区使用的协议,最常见的 TCP 和 UDP 协议的协议号分别是 6 和 17。

注2:SCTP 协议就是一个 RFC 标准中的传输层协议,但是 NAT 设备的兼容性问题会导致 SCTP 报文被丢弃。

由于 UDP 协议非常简单,很多新的传输层协议都会基于 UDP 实现,例如:Google 的 QUIC 协议。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 UDP 头只有 8 个字节 的相关文章

  • Android 8 细分版本 分支 以及支持的设备

    Android 8 细分版本 分支 以及支持的设备 细分版本分支版本支持的设备OPM8 181005 003android 8 1 0 r48OreoPixel COPM7 181005 003android 8 1 0 r47OreoNe
  • Android 打印堆栈日志的几种方法

    在Android调试过程中经常会出现程序出现的结果不是我们预期的结果 xff0c 那就需要加Log打印调试 xff0c 看调用过程是否正确 xff0c 此时就需要打印程序的调用栈 xff0c 特别是Android代码相当庞大 xff0c 打
  • 在 Ubuntu 18.04 上安装 SmartGit

    在开始安装之前 xff0c 很有趣 确保我们系统中的所有软件包都是最新的 为此 xff0c 在终端 Ctl 43 Alt 43 T 中 xff0c 我们只需编写 xff1a 1 sudo apt update sudo apt upgrad
  • 复工第一事:干掉 Notepad++

    点击上方 芋道源码 xff0c 选择 设为星标 管她前浪 xff0c 还是后浪 xff1f 能浪的浪 xff0c 才是好浪 xff01 每天 10 33 更新文章 xff0c 每天掉亿点点头发 源码精品专栏 原创 Java 2021 超神之
  • Ubuntu18.04编译Android8.0系统源码

    首先 需要一个台式电脑 xff0c 有个i7处理器 xff0c 有一个1T的机械 43 500G的固态 xff0c 如果条件允许改一个服务器也可以 我这里是一个台式电脑 在台式电脑上安装一个虚拟机 xff0c 基本是使用的VMware xf
  • m, mm以及mmm编译命令以及make snod的使用

    1 xff09 编译指定Package Android源码目录下的build envsetup sh文件 xff0c 描述编译的命令 croot 切到Android源码树的根目录 当你深入Android源码树的子目录 xff0c 想回到根目
  • 复杂条件逻辑的梳理

    为什么会感觉有些需求无从下手 在产品需求梳理或者业务逻辑调研阶段 xff0c 有时会遇到产品需求无从下手的问题 xff0c 分析下来 xff0c 一般情况如下 xff1a 需求边界不明确 xff0c 输入和输出的界定不清晰 xff0c 无法
  • Android源码刷机步骤

    打开OEM开关 xff1a 先点击设置 关于手机 版本号七次 开发者选项 打开OEM解锁 xff08 这步必须可以上网 xff0c 否则打不开 xff09 进入bootloader页面 使用方法1必须安装adb platform tools
  • Android Studio导入和调试Android8.0源码

    生成IDE相关文件 idegen专门为IDE环境调试源码而设计的工具 xff0c 依次执行如下命令 xff1a source build envsetup sh mmm development tools idegen developmen
  • make snod注意事项-刷机后启动异常

    1 正确执行顺序 需要执行 source build envsetup sh lunch 2 单独编译 xff0c 刷机后运行异常 全编andorid后 xff0c 单独修改编译一个framwork模块 xff0c make snod会有如
  • adb remount 系统提示只读文件系统Read-only file system,解决用adb disable-verity

    在Android6 0 xff08 Android M xff09 userdebug版本上 eng版本不存在该问题 xff0c 发现使用adb remount 系统之后 xff0c 还是不能对system分区进行操作 xff0c 提示没有
  • 枚举 switchcase 标签必须为枚举常量的非限定名称

    enum switch case label must be the unqualified name of an enumeration constant 或 错误 枚举 switchcase 标签必须为枚举常量的非限定名称case Co
  • VMware为什么会越用占用的内存越大?该如何清理?

    现象描述 xff1a VMware用了一段时间后发现原来刚开始只占5G左右的内存 xff0c 慢慢的会占用几十个G xff0c 甚至更多 xff0c 磁盘空间占用越来越大 解决办法 xff1a 虚拟机内部执行cat dev zero gt
  • H264中的时间戳(DTS和PTS)

    xff08 1 xff09 Ffmpeg中的DTS 和 PTS H264里有两种时间戳 xff1a DTS xff08 Decoding Time Stamp xff09 和PTS xff08 Presentation Time Stamp
  • UEFI/Legacy两种启动模式下安装Win10/Ubuntu双系统

    文章目录 更多操作细节请移步到 UEFI Legacy两种启动模式下安装Win10 Ubuntu双系统 http www aigrantli com archives uefilegacy E4 B8 A4 E7 A7 8D E5 90 A
  • H264视频编码原理

    一 为什么要对视频编码 视频是由一帧帧的图像组成 xff0c 就像gif图片一样 一般视频为了不会让人感觉到卡顿 xff0c 一秒钟至少需要16帧画面 一般30帧 加入该视频是一个1280x720的分辨率 xff0c 那么不经过编码一秒钟传
  • H.264基础知识总结

    H264是视频编解码格式 xff1b 学习H264之前首先要搞明白一个问题 xff0c 视频为什么要编码 xff0c 编码传输不行吗 xff1f 视频就是一堆图片按时间顺序播放 xff0c 在编码标准出现之前 xff0c 不经过编码的原始码
  • linux文件分割(将大的日志文件分割成小的)

    linux文件分割 xff08 将大的日志文件分割成小的 xff09 linux下文件分割可以通过split命令来实现 xff0c 可以指定按行数分割和安大小分割两种模式 Linux下文件合并可以通过cat命令来实现 xff0c 非常简单
  • 华为AGC性能管理功能sdk集成

    集成SDK 1 xff09 在AGC网站的我的项目中选择需要启用性能管理的应用 xff0c 点击质量 gt 性能管理 xff0c 进入性能管理服务页面 xff0c 立即开通服务 2 xff09 添加AGC插件 xff0c 在Android
  • Android平台集成华为AGC性能管理服务问题处理指南

    最近尝试集成了华为AGC的性能管理服务 xff0c 集成过程中也遇到一些问题 本文就对我在集成性能管理服务的踩坑记录进行总结 xff0c 希望能帮到大家 问题一 xff1a 刚集成性能管理服务 xff0c 报错miss client id

随机推荐

  • Android ANR全解析&华为AGC性能管理解决ANR案例集

    1 ANR介绍 1 1 ANR是什么 ANR xff0c 全称为Application Not Responding xff0c 也就是应用程序无响应 如果 Android 应用的界面线程处于阻塞状态的时间过长 xff0c 就会触发 应用无
  • JAVA包装类

    什么是包装类 虽然 Java 语言是典型的面向对象编程语言 xff0c 但其中的八种基本数据类型并不支持面向对象编程 xff0c 基本类型的数据不具备 对象 的特性 不携带属性 没有方法可调用 沿用它们只是为了迎合人类根深蒂固的习惯 xff
  • Rxjava理论(一)

    大家都知道RxJava上手是非常难的一个框架 xff0c 为什么说是难呢 xff0c 因为它的功能非常强大 xff0c 各种操作符让人很难上手 xff0c 搭配使用带生命周期的框架有RxLife等 以至于后面出了很多类似Rxjava的框架
  • rxjava理论(二)

    doOnSubscribe的监听 在上一节我们介绍过subscribeOn是控制上游的observable在哪个线程执行 xff0c 关于怎么控制上游的observable可以看我上篇文章RxJava面经一 xff0c 拿去 xff0c 不
  • RxJava Hook(钩子)方法

    Hook技术又叫钩子函数 xff0c 在系统没有调用函数之前 xff0c 钩子就先捕获该消息 xff0c 得到控制权 这时候钩子程序既可以改变该程序的执行 xff0c 插入我们要执行的代码片段 xff0c 还可以强制结束消息的传递 RxJa
  • android底层之什么是Zram?

    ZRAM的理解 ZRAM xff08 压缩内存 xff09 的意思是说在内存中开辟一块区域压缩数据 就是说假设原来150MB的可用内存现在可以放下180MB的东西 本身不会提高内存容量和运行速度 只是让后台程序更少被系统砍掉罢了 xff0c
  • rxjava - compose()操作符

    1 问题背景 想要给多个流重复应用 34 一系列 34 相同的操作符 该怎么办 比如 我们使用Rx 43 Retrofit进行网络请求时 都有遇到这样场景 要在io线程中请求数据 在主线程订阅 更新UI 所以必须频繁使用下面这样的代码 su
  • RxJava2 背压

    1 背压 在RxJava中 xff0c 会遇到被观察者发送消息太快以至于它的操作符或者订阅者不能及时处理相关的消息 xff0c 这就是典型的背压 Back Pressure 场景 BackPressure经常被翻译为背压 xff0c 背压的
  • MVVM实现与原理分析

    1 MVVM简介 1 1 MVC amp MVP amp MVVM MVP MVVM与MVP结构类似 xff0c MVP也是通过Presenter将View与Model解耦 不过MVVM是基于观察者模式 xff0c viewModel不持有
  • PCM数据格式

    什么是PCM PCM全称Pulse Code Modulation xff0c 翻译一下是脉冲调制编码 其实大可以不用关心英文释义 xff0c 之所以这么命名是因为一些历史原因 在音视频中 xff0c PCM是一种用数字表示采样模拟信号的方
  • 音频帧大小的计算

    音频aac mp3文档规定 xff1a AAC xff1a 帧大小1024个sample xff0c 采样率为44100Hz 帧播放时长 xff1a acc dur 61 1024 44100 61 0 02322s 61 23 22ms
  • Java多线程系列--join()

    1 join 介绍 join 定义在Thread java中 join 的作用 xff1a 让 主线程 等待 子线程 结束之后才能继续运行 这句话可能有点晦涩 xff0c 我们还是通过例子去理解 xff1a 主线程 public class
  • Android的设计模式-装饰者模式

    1 定义 动态地给一个对象添加一些额外的职责 就增加功能来说 xff0c 装饰模式相比生成子类更为灵活 2 介绍 装饰者模式属于结构型模式 装饰者模式在生活中应用实际上也非常广泛 xff0c 一如一间房 xff0c 放上厨具 xff0c 它
  • android音频焦点Audio Focus

    为了便于理解 xff0c 我们以android的8 0以前的版本为例 xff0c 8 0以后有一定改动 xff0c 但是基本思路一样 关于管理音频焦点 xff08 8 0以前和更高版本 xff09 的官方文档 xff1a https dev
  • Android音频通路的切换

    Android支持多种设备的的输出 一台正常的机子 xff0c 本身就自带话筒 xff0c 扬声器 xff0c 麦克风等多个声音输入输出设备 xff0c 再加上五花八门的外置设备 xff08 通过耳机 xff0c 蓝牙 xff0c wifi
  • Java实现基本数据结构——数组

    数组概念 所谓数组 xff0c 是有序的元素序列 若将有限个类型相同的变量的集合命名 xff0c 那么这个名称为数组名 在数据结构中 xff0c 数组是一种线性表 xff0c 就是数据排列成一条直线一样的结构 在内容空间中 xff0c 数组
  • 块元素居中方式

    1 定位 span class token doctype lt DOCTYPE html gt span span class token tag span class token tag span class token punctua
  • wireshark以太帧的分析

    首先应该明白 xff0c 封装以太帧的位于OSI七层模型的第二层 xff0c 也就是数据链路层 xff0c wireshark可以把完整的以太帧抓起来 xff0c 我们可以清楚的看到 打开wireshark找到自己ip对应的网卡 xff0c
  • 网络协议——七层、五层、四层协议概念及功能分析

    一 7层 7层是指OSI七层协议模型 xff0c 主要是 xff1a 应用层 xff08 Application xff09 表示层 xff08 Presentation xff09 会话层 xff08 Session xff09 传输层
  • 为什么 UDP 头只有 8 个字节

    为什么这么设计 xff08 Why s THE Design xff09 是一系列关于计算机领域中程序设计决策的文章 xff0c 我们在这个系列的每一篇文章中都会提出一个具体的问题并从不同的角度讨论这种设计的优缺点 对具体实现造成的影响 如