【网络编程】十、详解 UDP 协议

news2025/5/19 1:20:07

文章目录

  • Ⅰ. 传输层概述
    • 1、进程之间的通信
    • 2、再谈端口号
      • 端口号的引出
      • 五元组标识一个通信
      • 端口号范围划分
      • 常见的知名端口号
      • 查看知名端口号
      • 协议号 VS 端口号
    • 3、两个问题
      • 一个端口号是否可以被多个进程绑定?
      • 一个进程是否可以绑定多个端口号?
    • 4、部分常见指令
      • pidof(用于查看进程id)
      • netstat(查看网络状态)
  • Ⅱ. UDP协议
    • 1、UDP协议所处位置
    • 2、UDP协议格式
      • 如何理解首部?
      • UDP协议如何将首部与有效载荷进行分离?
      • UDP协议如何决定将有效载荷交付给上层的哪一个协议?
    • 3、UDP的主要特点
    • 4、面向数据报
    • 5、UDP协议的缓冲区
      • 为什么UDP要有接收缓冲区?
    • 6、基于UDP的应用层协议

在这里插入图片描述

Ⅰ. 传输层概述

1、进程之间的通信

​ 在学习 HTTP 等应用层协议时,为了便于理解,可以简单的认为 HTTP 协议是将请求和响应直接发送到了网络当中。但实际应用层需要先将数据交给传输层,再由传输层对数据做进一步处理后再将数据继续向下进行交付,该过程贯穿整个网络协议栈,最终才能将数据发送到网络当中。
在这里插入图片描述

​ 传输层负责可靠性传输,确保数据能够可靠地传送到目标地址。从通信和信息处理的角度看,运输层为它上面的应用层提供通信服务
在这里插入图片描述

​ 但是我们要明确的是,真正进行通信的实体,其实是主机中的应用进程,也就是进程之间的通信!而为了达到传输层向上服务应用层的时候,可以找到对应的进程,就有了两个重要的功能:复用分用!如下图所示:
在这里插入图片描述

​ 此外,传输层还要对收到的报文进行差错检测,只不过 传输层只检验首部是否出现差错,而不检查有效载荷部分!

2、再谈端口号

端口号的引出

​ 应用层所有的应用进程都可以通过运输层再传送到网络层,这叫做复用;而运输层从网络层收到发送给各应用进程的数据后,必须分别交付指明的各应用进程,这就是分用。

​ 所以很明显,给应用层的每个应用进程赋予一个非常明确唯一的标志是至关重要的

​ 我们知道,一台计算机中的进程有着唯一标识的进程标识符,但因为这个进程标识符和操作系统是强相关的,如果我们将其作为复用和分用的标识的话,那么会有一个问题,就是一个进程的标识符由操作系统管理,所以进程的销毁和创建都会导致进程标识符的变化,但是我们又是希望在网络中传输的时候,对方的唯一标志可以是尽量保持不变的(因为一旦变化,请求连接的标识也需要改变),所以我们 不能用进程标识符作为复用和分用的唯一标志

​ 所以此时就有人使用了端口号这种方案来作为唯一标识!

端口号(Port)标识一个主机上进行网络通信的不同的应用程序。当主机从网络中获取到数据后,需要自底向上进行数据的交付,而这个数据最终应该交给上层的哪个应用处理程序,就是由该数据当中的目的端口号来决定的。

​ 从网络中获取的数据在进行向上交付时,在传输层就会提取出该数据对应的目的端口号,进而确定该数据应该交付给当前主机上的哪一个服务进程。
在这里插入图片描述

​ 因此端口号是属于传输层的概念的,在传输层协议的报头当中就会包含与端口相关的字段。

​ 请注意,端口号只具有本地意义,在互联网不同的计算机中,相同的端口号是没有关联的!

五元组标识一个通信

​ 在 TCP/IP 协议中,用 “源IP地址”、“源端口号”、“目的IP地址”、“目的端口号”、“协议号” 这样一个五元组来标识一个通信。

​ 比如有多台客户端主机同时访问服务器,这些客户端主机上可能有一个客户端进程,也可能有多个客户端进程,它们都在访问同一台服务器。
在这里插入图片描述

而这台服务器就是通过 “源IP地址”、“源端口号”、“目的IP地址”、“目的端口号”、“协议号” 来识别一个通信的。

  • 先提取出数据当中的目的 IP 地址和目的端口号,确定该数据是发送给当前服务进程的。
  • 然后提取出数据当中的协议号,为该数据提供对应类型的服务。
  • 最后提取出数据当中的源 IP 地址和源端口号,将其作为响应数据的目的IP地址和目的端口号,将响应结果发送给对应的客户端进程。
    在这里插入图片描述

​ 通过 netstat 命令可以查看到这样的五元组信息。
在这里插入图片描述

​ 其中的 Local Address 表示的就是源IP地址和源端口号,Foreign Address 表示的就是目的IP地址和目的端口号,而 Proto 表示的就是协议类型。

端口号范围划分

端口号的长度是 16,因此端口号的范围是 0 ~ 65535

  • 0 ~ 1023知名端口号。比如 HTTPFTPSSH 等这些广为使用的应用层协议,它们的端口号都是固定的。
  • 1024 ~ 65535操作系统动态分配的端口号。客户端程序的端口号就是由操作系统从这个范围分配的。

常见的知名端口号

有些服务器是非常常用的,这些服务器的端口号一般都是固定的:

  • ssh 服务器,使用 22 端口
  • ftp 服务器,使用 21 端口
  • telnet 服务器,使用 23 端口
  • dns 服务器,使用 53 端口
  • http 服务器,使用 80 端口
  • https 服务器,使用 443 端口

查看知名端口号

​ 我们可以查看 /etc/services 文件,该文件是记录网络服务名和它们对应使用的端口号及协议。
在这里插入图片描述

说明一下:文件中的每一行对应一种服务,它由 4 个字段组成,每个字段之间用 TAB 或空格分隔,分别表示“服务名称”、“使用端口”、“协议名称”以及“别名”。

协议号 VS 端口号

  • 协议号是存在于 IP 报头当中的,其长度是 8 位。协议号指明了数据报所携带的数据是使用的何种协议,以便让目的主机的 IP 层知道应该将该数据交付给传输层的哪个协议进行处理。
  • 端口号是存在于 UDPTCP 报头当中的,其长度是 16 位。端口号的作用是唯一标识一台主机上的某个进程。
  • 协议号是作用于传输层和网络层之间的,而端口号是作用于应用层于传输层之间的。

3、两个问题

一个端口号是否可以被多个进程绑定?

一个端口号绝对不能被多个进程绑定,因为端口号的作用就是唯一标识一个进程,如果绑定一个已经被绑定的端口号,就会出现绑定失败的问题。

一个进程是否可以绑定多个端口号?

一个进程是可以绑定多个端口号的,这与“端口号必须唯一标识一个进程”是不冲突的,只不过现在这多个端口唯一标识的是同一个进程罢了。

​ 我们限制的是从端口号到进程的唯一性,而没有要求从进程到端口号也必须满足唯一性,因此一个进程是可以绑定多个端口号的。

4、部分常见指令

pidof(用于查看进程id)

pidof httpServer | xargs kill -9 // xargs用于将管道前面获取的参数追加到该指令后面

netstat(查看网络状态)

n  拒绝显示别名,能显示数字的全部转化成数字
l  仅列出有在 Listen (监听) 的服务状态
p  显示建立相关链接的程序名
t(tcp)  仅显示tcp相关选项
u(udp)  仅显示udp相关选项
a(all)  显示所有选项,默认不显示LISTEN相关

Ⅱ. UDP协议

1、UDP协议所处位置

​ 网络套接字编程时用到的各种接口,是位于应用层和传输层之间的一层系统调用接口,这些接口是系统提供的,我们可以通过这些接口搭建上层应用,比如 HTTP。我们经常说 HTTP 是基于 TCP 的,实际就是因为 HTTPTCP 套接字编程上搭建的。

​ 而 socket 接口往下的传输层实际就是由操作系统管理的,因此 UDP 是属于内核当中的,是操作系统本身协议栈自带的,其代码不是由上层用户编写的,UDP 的所有功能都是由操作系统完成,因此网络也是操作系统的一部分。

2、UDP协议格式

​ 其格式如下:
在这里插入图片描述

  • 16 位源端口号:表示数据从哪里来。
  • 16 位目的端口号:表示数据要到哪里去。
  • 16 位整个报文长度:表示整个数据报(UDP 首部 + UDP 数据)的长度。
    • 这也就说明 UDP 最大可传输的长度为 2^1664KB(包含首部字段),如果需要 传输大于 64KB 的数据,就需要应用层多次分包,并在接收端手动拼装
  • 16 位检验和:如果 UDP 报文的检验和出错,就会直接将报文丢弃。

​ 之所以我们在应用层看到的端口号大部分都是 16 位的,比如使用 uint16_t 类型,其根本原因就是因为传输层协议当中的端口号就是 16 位的。

如何理解首部?

​ 操作系统是 C 语言写的,而 UDP 协议又是属于内核协议栈的,因此 UDP 协议也一定是用 C 语言编写的,所以 UDP 首部本质上是一个结构体对象或者包含位段的结构体,如下所示:

struct udphdr {
    uint16_t uh_sport;  /* 源端口号 */
    uint16_t uh_dport;  /* 目的端口号 */
    uint16_t uh_ulen;   /* UDP数据报长度(包括头部+数据) */
    uint16_t uh_sum;    /* 数据校验和 */
};

UDP数据封装:

  • 当应用层将数据交给传输层后,在传输层就会创建一个 UDP 报头类型的变量,然后填充报头当中的各个字段,此时就得到了一个 UDP 报头。
  • 此时操作系统再在内核当中开辟一块空间,将 UDP 报头和有效载荷拷贝到一起,此时就形成了 UDP 报文。

UDP数据分用:

  • 当传输层从下层获取到一个报文后,就会读取该报文的前 8 个字节,提取出对应的目的端口号。
  • 通过目的端口号找到对应的上层应用层进程,然后将剩下的有效载荷向上交付给该应用层进程。

UDP协议如何将首部与有效载荷进行分离?

UDP的报头当中只包含四个字段,每个字段的长度都是 16 位,总共 8 字节。因此 UDP 采用的实际上是一种定长报头,UDP 在读取报文时读取完前 8 个字节后剩下的就都是有效载荷了。

​ 而我们只需要提取报头中的 数据报长度 字段,减去 8 个字节,最后的大小就是有效载荷的长度,是可以直接读取上来的!

UDP协议如何决定将有效载荷交付给上层的哪一个协议?

UDP 上层也有很多应用层协议,因此 UDP 必须想办法将有效载荷交给对应的上层协议,也就是交给应用层对应的进程。

​ 应用层的每一个网络进程都会绑定一个端口号,服务端进程必须显示绑定一个端口号,客户端进程则是由系统动态绑定的一个端口号。UDP 就是通过报头当中的目的端口号来找到对应的应用层进程的。

​ 说明一下: 内核中用哈希的方式维护了端口号与进程 ID 之间的映射关系,因此传输层可以通过端口号得到对应的进程 ID,进而找到对应的应用层进程

3、UDP的主要特点

  1. 无连接。发送数据之前不需要建立连接。
  2. 使用尽最大努力交付。即 不保证可靠交付
  3. 面向报文UDP 一次传送和交付一个完整的报文。
  4. 没有拥塞控制。网络出现的拥塞不会使源主机的发送速率降低。很适合多媒体通信的要求。
  5. 支持一对一、一对多、多对一、多对多等交互通信。
  6. 首部开销小,只有 8 个字节。

​ 总结一点,就是【简单方便,但不可靠】。
在这里插入图片描述

​ 此外,应用程序必须选择合适大小的报文。若报文太长,IP 层在传送时可能要进行分片,降低 IP 层的效率。若报文太短,会使 IP 数据报的首部的相对长度太大,降低 IP 层的效率。

4、面向数据报

​ 应用层交给 UDP 多长的报文,UDP 就原样发送,既不会拆分,也不会合并,这就叫做面向数据报。

​ 比如用 UDP 传输 100 个字节的数据:

​ 如果发送端调用一次 sendto,发送 100 字节,那么接收端也必须调用对应的一次 recvfrom,接收 100 个字节,而不能循环调用 10recvfrom 去每次接收 10 个字节。

5、UDP协议的缓冲区

UDP 协议不需要考虑多个报文之间的粘连问题,因为 UDP 没有真正意义上的发送缓冲区。调用 sendto 函数会直接交给内核(应用层发一个,传输层送走一个),由内核将数据传给网络层协议进行后续的传输动作。

​ 但是 UDP 具有接收缓冲区。但是这个接收缓冲区不能保证收到的 UDP 报的顺序和发送 UDP 报的顺序一致。如果缓冲区满了,再到达的 UDP 数据就会直接被丢弃,所以 UDP 协议是一种不可靠、全双工的协议。
在这里插入图片描述

为什么UDP要有接收缓冲区?

​ 如果 UDP 没有接收缓冲区,那么就要求上层及时将 UDP 获取到的报文读取上去,如果一个报文在 UDP 没有被读取,那么此时 UDP 从底层获取上来的报文数据就会被迫丢弃。

​ 一个报文从一台主机传输到另一台主机,在传输过程中会消耗主机资源和网络资源。如果 UDP 收到一个报文后仅仅因为上次收到的报文没有被上层读取,而被迫丢弃一个可能并没有错误的报文,这就是在 浪费主机资源和网络资源

​ 因此 UDP 本身是会维护一个接收缓冲区的,当有新的 UDP 报文到来时就会把这个报文放到接收缓冲区当中,此时上层在读数据的时就直接从这个接收缓冲区当中进行读取就行了,而如果 UDP 接收缓冲区当中没有数据那上层在读取时就会被阻塞。因此 UDP 的接收缓冲区的作用就是,将接收到的报文暂时的保存起来,供上层读取。

6、基于UDP的应用层协议

  • NFS:网络文件系统
  • TFTP:简单文件传输协议
  • DHCP:动态主机配置协议
  • BOOTP:启动协议(用于无盘设备启动)
  • DNS:域名解析协议

当然,也包括自己写 UDP 程序时自定义的应用层协议。

在这里插入图片描述

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

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

相关文章

[目标检测] YOLO系列算法讲解

前言 目标检测就是做到给模型输入一张图片或者视频,模型可以迅速判断出视频和图片里面感兴趣的目标所有的位置和它 的类别,而当前最热门的目标检测的模型也就是YOLO系列了。 YOLO系列的模型的提出,是为了解决当时目标检测的模型帧率太低而提…

.NET NativeAOT 指南

目录 1. 引言 2. 什么是 .NET NativeAOT? 2.1 NativeAOT 的定义 2.2 NativeAOT 与传统 JIT 的对比 2.3 NativeAOT 的适用场景 3. NativeAOT 的核心优势 3.1 性能提升 3.2 简化部署 3.3 更小的应用体积 3.4 知识产权保护 4. NativeAOT 的基本用法 4.1 环境…

uniapp-商城-57-后台 新增商品(弹窗属性数据添加父级)

后台增加商品,需要添加相关的数据信息,这里还要添加属性,前面已经对相关的界面布局继续了编写。这里还要对页面添加的数据,置入到云数据库,继续永久保存,便于后期的使用。这里主要是讲属性数据 父级信息的添…

摩方 12 代 N200 迷你主机(Ubuntu 系统)WiFi 抓包环境配置教程

摩方12代N200迷你主机标配 Intel AX201无线网卡,支持 WiFi 6 协议(802.11ax)及蓝牙5.2。此网卡兼容主流抓包工具,但需注意: 驱动兼容性:Ubuntu 20.04及以上内核版本(5.4)默认支持AX2…

Unity(URP渲染管线)的后处理、动画制作、虚拟相机(Virtual Camera)

一、URP渲染管线 渲染管线是一系列渲染操作的集合,Unity提供了内置渲染管线(Built-In)和可编程渲染管线(SRP)两类渲染管线。内置渲染管线是Unity的默认渲染管线,其自定义选项有限。而可编程渲染管线可以通…

mac-M系列芯片安装软件报错:***已损坏,无法打开。推出磁盘问题

因为你安装的软件在Intel 或arm芯片的mac上没有签名导致。 首先打开任何来源操作 在系统设置中配置,如下图: 2. 然后打开终端,输入: sudo spctl --master-disable然后输入电脑锁屏密码 打开了任何来源,还遇到已损坏…

Echart地图数据源获取

DataV.GeoAtlas地理小工具系列 选择需要的区域地图,选中后输出即可: 地图钻取代码 <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>map</title><style>html, body, #map{margin: 0;…

GNSS数据自动化下载系统的设计与实现

摘要 本文详细介绍了三种不同设计的GNSS数据自动化下载系统&#xff0c;分别针对IGS观测数据、GRACE-FO Level-1B数据以及通过代理服务器获取数据的需求场景。系统采用Python实现&#xff0c;具备断点续传、完整性校验、异常处理和进度显示等核心功能。实验结果表明&#xff0…

Unity3D仿星露谷物语开发43之农作物生长

1、目标 把防风草种子种在地里&#xff0c;并展示植物种子&#xff0c;防风草种子将随着时间变化而生长成植株。 2、创建Crop.cs脚本 在Assets -> Scripts下创建新的目录命名为Crop&#xff0c;在其下创建新的脚本命名为Crop.cs。 代码如下&#xff1a; using System.C…

从0到1上手Kafka:开启分布式消息处理之旅

目录 一、Kafka 是什么 二、Kafka 的基础概念 2.1 核心术语解读 2.2 工作模式剖析 三、Kafka 的应用场景 四、Kafka 与其他消息队列的比较 五、Kafka 的安装与配置 5.1 环境准备 5.2 安装步骤 5.3 常见问题及解决 六、Kafka 的基本操作 6.1 命令行工具使用 6.1.1 …

Python爬虫如何应对网站的反爬加密策略?

在当今的互联网环境中&#xff0c;网络爬虫已经成为数据采集的重要工具之一。然而&#xff0c;随着网站安全意识的不断提高&#xff0c;反爬虫技术也越来越复杂&#xff0c;尤其是数据加密策略的广泛应用&#xff0c;给爬虫开发者带来了巨大的挑战。本文将详细介绍Python爬虫如…

第一次经历项目上线

这几天没写csdn&#xff0c;因为忙着项目上线的问题&#xff0c;我这阶段改了非常多的前端bug哈哈哈哈&#xff0c;说几个比较好的bug思想&#xff01; 这个页面算是我遇到的比较大的bug&#xff0c;因为我一开始的逻辑都写好了&#xff0c;询价就是在点击快递公司弹出弹框的时…

Conda配置完全指南——Windows系统Anaconda/Miniconda的安装、配置、基础使用、清理缓存空间和Pycharm/VSCode配置指南

本文同步发布在个人博客&#xff1a; Conda配置完全指南Conda 是一个开源的跨平台包管理与环境管理工具&#xff0c;广泛应用于数据科学、机器学习及 Python 开发领域。它不仅能帮助用户快速安装、更新和卸载第三方库&#xff0c;还能创建相互隔离的虚拟环境&#xff0c;解决不…

Quasar组件 Carousel走马灯

通过对比两个q-carousel组件来&#xff0c;了解该组件的属性 官方文档请参阅&#xff1a;Carousel 预览 源代码 <template><div class"q-pa-md"><div class"q-gutter-md"><q-carouselv-model"slide"transition-prev&quo…

风控域——风控决策引擎系统设计

摘要 本文详细介绍了风控决策引擎系统的设计与应用。决策引擎系统是一种智能化工具&#xff0c;可自动化、数据驱动地辅助或替代人工决策&#xff0c;广泛应用于金融、医疗、营销、风控等领域。文章阐述了决策引擎的核心功能&#xff0c;包括自动化决策、动态规则管理、实时处…

CAPL Class: TcpSocket (此类用于实现 TCP 网络通信 )

目录 Class: TcpSocketacceptopenclosebindconnectgetLastSocketErrorgetLastSocketErrorAsStringlistenreceivesendsetSocketOptionshutdown函数调用的基本流程服务器端的基本流程客户端的基本流程Class: TcpSocket学习笔记。来自CANoe帮助文档。 Class: TcpSocket accept /…

数据分析 —— 数据预处理

一、什么是数据预处理 数据预处理&#xff08;Data Preprocessing&#xff09;是数据分析和机器学习中至关重要的步骤&#xff0c;旨在将原始数据转换为更高质量、更适合分析或建模的形式。由于真实世界的数据通常存在不完整、不一致、噪声或冗余等问题&#xff0c;预处理可以…

软件架构风格系列(4):事件驱动架构

文章目录 前言一、从“用户下单”场景看懂事件驱动核心概念&#xff08;一&#xff09;什么是事件驱动架构&#xff1f;&#xff08;二&#xff09;核心优势&#xff1a;解耦与异步的双重魔法 二、架构设计图&#xff1a;三要素构建事件流转闭环三、Java实战&#xff1a;从简单…

arduino平台读取鼠标光电传感器

鼠标坏掉了&#xff0c;大抵是修不好了。&#xff08;全剧终—&#xff09; 但是爱动手的小明不会浪费这个鼠标&#xff0c;确认外观没有明显烧毁痕迹后&#xff0c;尝试从电路板上利用光电传感器进行位移的测量&#xff0c;光电传感器&#xff08;型号&#xff1a;FCT3065&am…

【Linux网络】网络层

网络层 在复杂的网络环境中确定一个合适的路径 IP 协议 IPV4 点分十进制[0,255].[0,255].[0,255].[0,255]IPV6 IP地址目标网格目标主机 基本概念 主机:配有IP地址,但是不进行路由控制的设备;路由器:即配有IP地址,又能进行路由控制;节点:主机和路由器的统称。 两个问题 路…