[Linux] UDP协议介绍:UDP协议格式、端口号在网络协议栈那一层工作...

2024-06-16 17:52

本文主要是介绍[Linux] UDP协议介绍:UDP协议格式、端口号在网络协议栈那一层工作...,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

TCP/IP网络模型, 将网络分为了四层:

|huge

之前的文章中以HTTPHTTPS这两个协议为代表, 简单介绍了应用层协议. 实际上, 无论是HTTP还是HTTPS等应用层协议, 都是在传输层协议的基础上实现的

而传输层协议中最具代表性的就是: UDPTCP协议了. 以HTTP为例, 在使用HTTP协议通信之前, 是先需要建立TCP连接的.

那么, 传输层协议的介绍就先从UDP协议开始

再谈端口号

在网络通信中, 端口号可以标识主机中的唯一进程.

我们在使用UDP/TCP Socket时, 都对服务器绑定过端口号. 在实际通信中, 当一个客户端向服务器发送数据时, 服务器主机接收到数据之后, 操作系统会 根据报文中的端口号 将数据推送给对应的进程

TCP/IP协议中, 通过 源IP、源端口、目的IP、目的端口、协议号 这样一个五元组标识一个通信

IP标记主机唯一性(用来寻找主机), 端口号标记进程唯一性(用来选择主机中的进程)

其中, 端口号实际是传输层的内容, 因为传输层向上就是应用层了, 那么传输层就需要解决将数据交给上层哪一个进程的问题

IP则是解决报文在网络中进行路由的问题, 需要通过 源IP和目的IP解决从哪来到哪去 的问题

实际上, 通过通过系统调用绑定的IP端口号, 是会使用在TCP/IP的不同层次中的: IP使用在网络层, 端口号则使用在传输层

端口号划分

端口号是16位的, 是因为传输层报头中存在16位用来存储端口号

那么端口号的范围就是: 0~66535

其中0~1023是知名端口号, 它特定分配给一些知名的应用层协议使用, 比如:

  1. SSH服务器, 使用22端口

  2. FTP服务器, 使用21端口

  3. TELNET服务器, 使用23端口

  4. HTTP服务器, 使用80端口

  5. HTTPS服务器, 使用443端口

  6. 知名端口号在/etc/services文件中存储着, 可以进行查看

    |wide

这些知名端口号一般是不允许分配给其他服务的

而剩下的1024~65535, 就是操作系统可以动态分配的端口号, 也可以被指定.

UDP协议

之前介绍过, 主机发送数据通过不同的层级时, 不同的协议是会对数据添加报头的

即之前我们使用sendto()等一系列系统调用时, 并不是直接将数据发送到了另一套主机上, 而是由操作系统给网络的下一层, 添加对应的协议报头:

PC1 |inline

不同协议会添加自己的报头, 下面就介绍一下UDP协议的格式

UDP协议格式

UDP协议的格式可以用一张图来表示

从图中可以看到出, UDP协议报头部分是固定的8个字节, 剩下的则是应用层传输过来的原始数据, 即有效载荷

UDP协议的报头非常容易理解

首先, 这里有三个概念简单理解一下:

传输层协议接收到来自上层的数据之后, 需要添加自己的协议报头, 这个行为叫 封装. 封装之后, 就可以将数据继续向下层传输

直到对应主机的传输层收到封装数据之后, 层协议需要对封装数据进行 解包, 分别读取数据和报头

之后, 传输层还需要将获取到的数据内容 传输到 指定应用层进程的可用空间, 这个行为叫 分用

实际上, TCP/IP的每层都要考虑如何封装、解包和分用的问题


UDP协议使用固定长度的报头长度, 就很好的解决了如何封装和解包的问题

主机1在使用UDP协议发送数据时, 只需要在原始数据前加上这8字节的报头就可以 实现封装

对方主机获取到数据之后, 只需要去掉前8个字节, 就可以获取有效载荷 实现解包

而, 分用的实现 就需要读取UDP报头的内容了

UDP报头中存在 16位的源端口号16位的目的端口号. 当主机接收到UDP报文之后, 读取报头中存储的 16位目的端口号, 就可以知道要向哪一个应用层进程的可用空间传输数据了. 即 可以实现分用

Linux中, 一切皆文件. 我们之前也介绍过socket套接字, 实际就是文件描述符

当传输层协议知道应用层对应服务的端口号之后, 就可以找到对应的进程, 然后就可以找到进程对应的网络文件, 将数据写入到网络文件的文件缓冲区中

进程服务就可以读取数据了

而, 16位UDP长度该作何理解呢?

16位UDP长度表示, UDP报文的整体长度, 而不是单指有效载荷的长度

我们知道, UDP协议的特点之一是 面向数据报

面向数据报就表示, 每一个UDP数据报都应该是完整的. 两个数据报之间是具有明显的边界的.

当接收主机接收到多个UDP报文时, 可以通过读取每个报头中的UDP长度来准确的获取到完整的UDP报文, 而不产生混乱

而, 16位检验和则用于检验报文内容是否出现了差错等, 如果出现了差错操作系统就会直接丢弃掉整个报文(这就是UDP协议 不可靠 的表现)

UDP协议的不可靠是否看作一种缺点?

不能将 不可靠 看作UDP协议的缺点, 不可靠 是UDP协议的特点

使用UDP协议通信, 数据报发生损坏会被直接丢弃. 这使UDP协议可以使用在一些 对数据丢失有一定的容忍度的 一些特定的场景中, 比如: 视频直播

视频直播可以容忍短暂的卡顿和画面丢失, 但是需要保证直播内容的持续输出. 类似这样的场景中, UDP协议可以很好的适配

也就是说, 不可靠 不是一种缺点 而是一种特点, 可以用在更合适的场景中

UDP不可靠, 也就意味这它不用像TCP那样 需要做一系列的保证数据可靠的操作和处理, 也就不用非常的复杂


总的来说, UDP协议的格式就是8字节的UDP报头+原始数据

UDP协议报头在Linux中的格式

那么, 使用UDP协议通信时, 操作系统在传输层添加协议报头时, 是以什么形式添加的, UDP报头的本质是什么?

网络协议栈TCP/IP是在Linux内核中实现的, Linux内核是由C语言实现的

而Linux内核中, UDP报头的实现就是一个结构体:

Linux_2.6.38_Kernel |large

这就意味着, 操作系统使用UDP协议封装数据时, 是以结构体的形式添加的UDP协议报头, 因为UDP协议报头的格式在Linux内核中的实现方式就是一个结构体

那么, 我们使用UDP协议创建网络套接字时候, 需要将套接字bind()到特定的端口上

然后在使用sendto()进行发送数据时, 操作系统就会创建udphdr对象并填充端口号、内容以及检验和. 并将udphdr对象以一定的形式拷贝到原始数据之前. 形成一个完整的UDP报文

UDP的缓冲区

在Linux系统中, 我们无论使用UDP还是TCP进行通信, 无论是使用sendto()还是write()向网络中发送数据

实际上, 在函数执行完毕之后都没有直接将数据发送到网络中, 而是在操作系统对数据进行处理了之后, 将数据放入到 发送缓冲区 中, 什么时候真正的发送出去, 由操作系统内核决定

所以, 要理解一个东西: sendto()write()并不是发送的接口, 而是拷贝的接口. 调用这两个接口, 都只是将数据拷贝到内核中, 而不是制剂发送到网络中或者直接写入到内核中

接收数据也是一样的, 操作系统接收网络数据时, 从网络层到传输层 也会将数据暂时存储到接收缓冲区, 等待内核中传输层的接收、解包以及分用

实际上, UDP协议在内核中并没有真正意义上的发送缓冲区

首先, 因为使用UDP协议在发送数据时, 操作系统需要对数据进行的处理动作很简单, 毕竟udphdr是一个很简单的只有8字节的结构体, 只需要添加一个结构体就可以. 并且UDP协议不需要保证数据可靠性, 这也就意味着UDP协议不需要将发送的数据在本地长时间维护, 也就不需要一个真正的发送缓冲区

这意味着, 当使用sendto()将数据交给内核时, 内核会尽快的将数据发送到网络层, 不需要在传输层存储数据

不过, 虽然UDP协议并没有发送缓冲区, 但 UDP协议是有接收缓冲区的

也就是说, Linux系统内核中维护有一块空间 专门存储收到的UDP报文数据, 并且 针对每一个UDP套接字都会维护那一块空间, 这就是内核中UDP的接收缓冲区

当操作系统接收到UDP协议数据报时, UDP协议会对UDP数据报进行解包, 然后再将数据存储到对应UDP Socket的接收缓冲区中, 这个过程实际就是UDP协议对UDP数据报解包和分用的过程

但是, UDP协议是面向数据报的. 使用UDP协议通信发送数据时, 都是以一个数据报一个数据报的形式发送的. 但是UDP协议的接收缓冲区是 不保证 接收到UDP数据报的顺序 与 发送端发送UDP数据报的顺序 是一致的(即, 如果发送端按照12345的顺序发送数据报, 接收端很可能并不是按照12345的顺序接收到的)

UDP数据报的发送顺序与接收顺序可能一致, 也体现了UDP协议的不可靠性

因为无法保证UDP数据报的接收顺序, 所以如果有顺序一致的需求, 那么接收端就需要对UDP数据报进行重排序, 一般在发送方和接收方的应用层实现

并且, UDP协议接收缓冲区满了之后, 再发送过来的UDP数据报会被直接丢弃

UDP协议发送端与接收端的 发送 与 接收 是互不影响的, 所以UDP协议是全双工的. 使用UDP协议可以同时发送和接收数据报

UDP报文大小

UDP报文首部中, 有一块16位的空间 是用来存储UDP报文总长度的

那么也就意味着: 一个UDP报文, 最大也就 2的16次方个字节, 即 64KB(包括8字节首部)

64KB在现在是非常的小的. 那么, 如果使用UDP协议传输大一点(超过64KB)的文件时, 就需要在应用层进行分包, 多次发送. 对应的, 接收端同样需要对接受的数据进行手动拼装.


这就是关于UDP协议简单介绍的全部内容了

感谢阅读~

这篇关于[Linux] UDP协议介绍:UDP协议格式、端口号在网络协议栈那一层工作...的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1067141

相关文章

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个

ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法

《ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法》本文介绍了Elasticsearch的基本概念,包括文档和字段、索引和映射,还详细描述了如何通过Docker... 目录1、ElasticSearch概念2、ElasticSearch、Kibana和IK分词器部署

Linux流媒体服务器部署流程

《Linux流媒体服务器部署流程》文章详细介绍了流媒体服务器的部署步骤,包括更新系统、安装依赖组件、编译安装Nginx和RTMP模块、配置Nginx和FFmpeg,以及测试流媒体服务器的搭建... 目录流媒体服务器部署部署安装1.更新系统2.安装依赖组件3.解压4.编译安装(添加RTMP和openssl模块

linux下多个硬盘划分到同一挂载点问题

《linux下多个硬盘划分到同一挂载点问题》在Linux系统中,将多个硬盘划分到同一挂载点需要通过逻辑卷管理(LVM)来实现,首先,需要将物理存储设备(如硬盘分区)创建为物理卷,然后,将这些物理卷组成... 目录linux下多个硬盘划分到同一挂载点需要明确的几个概念硬盘插上默认的是非lvm总结Linux下多

linux进程D状态的解决思路分享

《linux进程D状态的解决思路分享》在Linux系统中,进程在内核模式下等待I/O完成时会进入不间断睡眠状态(D状态),这种状态下,进程无法通过普通方式被杀死,本文通过实验模拟了这种状态,并分析了如... 目录1. 问题描述2. 问题分析3. 实验模拟3.1 使用losetup创建一个卷作为pv的磁盘3.

使用C++将处理后的信号保存为PNG和TIFF格式

《使用C++将处理后的信号保存为PNG和TIFF格式》在信号处理领域,我们常常需要将处理结果以图像的形式保存下来,方便后续分析和展示,C++提供了多种库来处理图像数据,本文将介绍如何使用stb_ima... 目录1. PNG格式保存使用stb_imagephp_write库1.1 安装和包含库1.2 代码解

Linux环境变量&&进程地址空间详解

《Linux环境变量&&进程地址空间详解》本文介绍了Linux环境变量、命令行参数、进程地址空间以及Linux内核进程调度队列的相关知识,环境变量是系统运行环境的参数,命令行参数用于传递给程序的参数,... 目录一、初步认识环境变量1.1常见的环境变量1.2环境变量的基本概念二、命令行参数2.1通过命令编程

Linux之进程状态&&进程优先级详解

《Linux之进程状态&&进程优先级详解》文章介绍了操作系统中进程的状态,包括运行状态、阻塞状态和挂起状态,并详细解释了Linux下进程的具体状态及其管理,此外,文章还讨论了进程的优先级、查看和修改进... 目录一、操作系统的进程状态1.1运行状态1.2阻塞状态1.3挂起二、linux下具体的状态三、进程的

Linux编译器--gcc/g++使用方式

《Linux编译器--gcc/g++使用方式》文章主要介绍了C/C++程序的编译过程,包括预编译、编译、汇编和链接四个阶段,并详细解释了每个阶段的作用和具体操作,同时,还介绍了调试和发布版本的概念... 目录一、预编译指令1.1预处理功能1.2指令1.3问题扩展二、编译(生成汇编)三、汇编(生成二进制机器语

Rsnapshot怎么用? 基于Rsync的强大Linux备份工具使用指南

《Rsnapshot怎么用?基于Rsync的强大Linux备份工具使用指南》Rsnapshot不仅可以备份本地文件,还能通过SSH备份远程文件,接下来详细介绍如何安装、配置和使用Rsnaps... Rsnapshot 是一款开源的文件系统快照工具。它结合了 Rsync 和 SSH 的能力,可以帮助你在 li