七.传输层协议——再谈UDP协议

news2025/3/19 0:36:36

一.传输层协议地位

在上一节中,我们提到到了HTTP,HTTPS等应用层协议,现在我们就要进一步向下挖掘,来到我们的传输层协议
假如说应用层负责传递的是数据的内容,专注于为⽤户提供应⽤功能;那传输层协议负责的就是传输的策略问题,这就好比我们运送快递,把东西交给顺丰就够了,至于怎么发,什么时候发,并不是我上层应用层关心的问题!运送快递的时间,方式(策略)是由我们的传输层负责的.
在传输层中会有两个主要协议
一个称作UDP协议,简单到只负责发送数据包,不保证数据包是否能抵达到对方那,但它有一个最大的特点,就是简单!传输效率⾼,这在我们之前用套接字编写的时候已经体会过了(PS:UDP协议也可以实现可靠传送,只需要按照TCP特性,对它进行上层封装即可,当然假如要用UDP实现商用,这就不是一件简单的事情了,早期的QQ实际上就是采用UDP协议进行传输数据)
另一个称作TCP协议,英文名为Transmission Control Protocol,⼤部分应⽤现在使⽤的都是TCP 传输层协议,它最大的特点就是能保证数据包能可靠地传输给对方,当然代码编写难度也相对增大许多,这在我们之前编写时也已经了解到
我们本章谈的主要还是UDP协议,进一步了解它的特性和设计细节

二.再谈端口号

2.1 Port号

我们之前提到过,当设备作为接收方时,传输层则要负责把数据包传给对应的应用,但是⼀台设备上可能会有很多应⽤在接收或者传输数据(很多个进程),总不能你使用QQ发送数据,最后发送的语音信号到了对方的微信中去吧
因此需要用⼀个编号将应⽤区分开来,这个编号就是我们的端口号,它用于标识了一个主机上进行通信的不同的应用程序
当然,这里还是把我们之前所疑惑的地方再啰嗦一遍

Q1.
每一个进程不是都有对应的进程pid吗?用pid进行标识不也可以吗?为什么要单独再设计一个端口号的概念呢?
1.不是所有的进程都要进行网络通信,假如用PID来标识,就很难进行区分,这个进程到底要不要进行网络通信呢?
2.解耦,进程PID还牵连到进程管理,我们希望的是进程管理,与网络两者可以区分开来,自成一套体系
Lg.这就好像我们每个人都有自己的身份证号,用来标识我们的唯一性,但我们在学校也有自己的学号!它也可以用来标识我们在学校的唯一性,对学号的处理,并不会改变我们的身份证号,学校管理和国家进行行政管理,这是两套不同的管理体系,互不干扰

Q2.
一个端口号可以被多个进程绑定吗?
不允许!!!
那就没有区分不同进程这一说法了
一个进程可以关联多个端口号吗?
可以!!!
这主要是能够实现多路复用的功能,通过关联多个端口号,一个进程可以同时监听或处理多个网络连接。这种多路复用的机制允许一个进程同时与多个客户端通信,而无需为每个连接创建一个独立的进程

Q3.
常见端口号划分
(1)0 - 1023: 知名端口号, HTTP, FTP, SSH等这些广为使用的应用层协议, 他们的端口号都是固定的.

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

我们可以使用下面的指令查看对应的端口号是否被占用,然后自己在编写对应程序的时候,要避开这些知名端口号

cat /etc/services

1024 - 65535:
操作系统动态分配的端口号. 客户端程序的端口号, 就是由操作系统从这个范围分配的,前面我们也提到过了,这主要是防止我们用户端的应用程序端口号大家设计一样,导致用户比如打开百度浏览器,就不能再打开QQ的尴尬情况

2.2 netstat指令

在TCP/IP协议中,我们用源ip,源端口号,目的ip,目的端口号,协议号,五元组来标识一个通信
具体过程如下:
1.先提取出数据当中的目的IP地址和目的端口号,确定该数据是发送给当前服务进程的。
2.提取出数据当中的协议号,为该数据提供对应类型的服务.
(协议号和端口号不同!协议号是存在于IP报头当中的,长度是8位,作用是指明数据报所携带的数据是使用的何种协议;而端口号是存在于TCP或UDP报头当中,作用就是我们提到过的,标识网络中的唯一进程)
3.提取出数据当中的源IP地址和源端口号,将其作为响应数据的目的IP地址和目的端口号,将响应结果发送给对应的客户端进程
在linux系统下,我们可以用这样的指令进行查看对应不同进程的网络状态

netstat -n

常见选项主要有下面四个

n(number) 能显示数字的就显示成数字
t 只查tcp
u 只查udp
p 进程pid
l 只查看listen监听情况

一般我们都习惯四个选项都用上,不然输出的进程网络状态太多了
当然这里还有个注意点,假如你想要将所有的进程网络状态都看到,还需要切换到root,才有对应的权限
在这里插入图片描述
我们切换为root后,就没有上面那句提示了
在这里插入图片描述

2.3 iostat指令

iostat指令主要用于输出磁盘IO和CPU的统计信息
常见的选项有下面几种

c:显示CPU的使用情况。
d:显示磁盘的使用情况。
N:显示磁盘列阵(LVM)信息。
n:显示NFS使用情况。
k:以KB为单位显示。
m:以M为单位显示。
t:报告每秒向终端读取和写入的字符数和CPU的信息。
V:显示版本信息。
x:显示详细信息。
p:显示磁盘分区的情况。

假如在Linux系统中尝试使用iostat命令,但系统提示没有这个指令,那么可能是没有安装sysstat包
还需要用指令安装sysstat包

sudo yum install sysstat

在这里插入图片描述

一般我们使用的时候,带个-x选项即可查看IO设备和CPU的详细使用情况
在这里插入图片描述

2.4 Pidof指令

通过pidof指令,我们可以轻松通过进程名, 就能查看对应的进程id,配合kill指令,能够轻松杀死对应的进程

pidof [进程名]

在编写TCP网络服务器时,我们曾经提到过守护进程的概念
守护进程是个特殊的孤儿进程,脱离终端而存在,能够避免进程被任何终端所产生的信息所打断,并且它执行过程中的信息也不在任何终端上显示
守护进程的名字,一般以d结尾
和终端脱离关系,自己在运行,我们会想到什么呢?
有时候有一个终端一直死循环打印,但我们依旧可以验证用户,创建新的终端(子进程),这个程序不就是守护进程吗?
我们可以调用下面的指令查看

ps axj | head -1 && ps axj | grep sshd

可以看到,无论是我们的root还是zzq用户,都是这个守护进程的子进程
在这里插入图片描述
输入我们刚学习的指令pidof,验证一下,是否真的能通过进程名,拿到对应的进程PID
在这里插入图片描述

三.UDP协议

3.1 协议端格式

在这里插入图片描述

16位源端口号:表示数据从哪里来。
16位目的端口号:表示数据要到哪里去。
16位UDP长度:表示整个数据报(UDP首部+UDP数据)的长度。
16位UDP检验和:如果UDP报文的检验和出错,就会直接将报文丢弃。
数据:就是我们上层应用层交付下来的,诸如HTTP请求等等

无论学习哪个协议,最关键的就是两个问题,如何分离与向上交付

第一.报头和有效载荷是如何分离的? 不然我们无法做到向上交付
当然,对于UDP协议来说,这个问题比较简单
我们可以发现,报头它是固定八个字节的,只要读取前八个字节,就能获取到报头,剩下的就是我们的数据

第二.有效载荷是如何向上做到交付的呢?
我们说了对面服务端可能有多个进程,每个进程至少含有一个端口Port号,有效载荷(数据)怎么知道要发给谁呢?
答案前面我们也已经揭晓了,UDP协议格式中16位目的端口号在那摆着呢!我们通过目的端口号就能找到对应的应用层进程

3.2 封装与解包

那现在我们就要进一步思考一个问题了,到底什么叫做封装呢?什么又叫做解包呢?
你直接给我展示出UDP协议端格式,让人摸不着头脑的晕
我们知道tcp/Ip是属于操作系统的,即它的实现其实并不是我们用户做,大佬已经帮我们写好了,我们使用的是他们写好的接口而已
而Linux系统我们知道,是用C语言写的
所以不难得出一个结论,UDP是用C语言实现的
那C语言中涉及管理不同类型数据的结构是什么呢?
答案就是结构体!
所以报头(协议)的本质就是一个结构化数据!(Struct结构体)
我们的UDP报头实际就是一个位段类型
在这里插入图片描述
我们所谓的封装

第一步,就是接收相应从用户层传下的数据
第二步,往结构体里面对应位置填充对应的数据,得到UDP报头
第三步,定义更大的缓冲区,往里面填有效载荷,将UDP报头和有效载荷拷贝到一起,此时就形成了UDP报文

在C语言中,先用char* 指针p指向结构体最开始,然后强转为对应的struct udp_header* 指针,往里面填数据即可
在这里插入图片描述
那什么是解包呢?
对于我们的结构体来说,它的报头,有效字段是已经定义好的
从里面依次取数据,就是我们的解包,根本没有我们想象中那么复杂
start指针+sizeof报头字节大小,就能取出我们的有效载荷
在这里插入图片描述
由于协议标准规定,所以UDP协议跨越平台!不需要像我们的应用层一样考虑序列化,反序列化等等问题

3.3 特点

3.3.1 面向数据报

应用层交给udp多长的报文,udp原样进行发送,既不会拆分,也不会进行合并,发多少,收多少,这被我们称作面向数据报.
比如用UDP传输100个字节的数据:
如果发送端调用一次sendto,发送100字节,那么接收端也必须调用对应的一次recvfrom,接收100个字节

3.3.2 缓冲区

UDP没有真正意义上的发送缓冲区,一旦调用类似sendto的系统接口,就会直接把数据进行封装,然后由内核交付给下层网络层发送
但它是具有接收缓冲区的,原因就在于假如没有接收缓冲区,对面没有接收到数据而直接选择丢弃可能正确的报文,综合考量下来,效率底下
因此,当有新的UDP报文到来时就会把这个报文放到接收缓冲区当中,此时上层在读数据的时就直接从这个接收缓冲区当中进行读取就行了,而如果UDP接收缓冲区当中没有数据那上层在读取时就会被阻塞
需要注意的是,接收缓冲区不能保证接收到的数据顺序,和我们发送出去的数据顺序是一致的,这也是UDP相对TCP没有那么可靠的体现之一
假如接收缓冲区满了,此时才会把对面发过来的数据丢弃,单个报文最多64KB,然而64K在当今的互联网环境下, 是一个非常小的数字.
所以,如果我们需要传输的数据超过64K, 就需要在应用层手动的分包, 多次发送, 并在接收端手动拼装

3.4 基于UDP协议的应用层协议

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

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

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

相关文章

EXCEL从图片链接获取图片

step1: 选中图片地址列 step2:开发工具→Visual Basic 文件→导入 导入我制作的脚本(代码见文章末尾) 点击excel的小图标回到表格界面。 点击【宏】 选中刚才导入的脚本,点执行,等待完成。 代码本体: Sub InsertPict…

最大堆,最小堆,优先队列,堆排序 LC例题-找第K大元素

LC215 数组中的第K个最大元素 class Solution {static Comparator<Integer> cmp new Comparator<Integer>(){Overridepublic int compare(Integer i1, Integer i2){return i1 - i2;//升序排列// return i2 - i1&#xff1b;//降序}}; public static int findKthL…

Linux中,ll 命令 列出目录的内容

文章目录 1、2、3、4、5、 1、 在Linux中&#xff0c;ll 通常是一个别名&#xff08;alias&#xff09;用于 ls -l 命令。ls 命令用于列出目录的内容&#xff0c;而 -l 选项会以长格式&#xff08;long format&#xff09;显示信息&#xff0c;包括文件或目录的权限、所有者、…

android 开机动画执行流程

android深入了解开机动画 开机动画的种类 1&#xff1a;View绘制 2&#xff1a;逐帧动画&#xff1a;比较主流的方式&#xff0c;一般动画的文件打包成 bootanimation.zip 存储到 /system/media/ 下。一般.zip文件 > 5M 就会有明显的卡顿&#xff0c;所以一般开机动画只有…

[next.js]pwa缓存

配置Next.js (v14 App Router模式) 使其支持PWA缓存&#xff0c;配置server worker和mainfest.json&#xff0c;让项目支持离线访问和可安装。 安装依赖next-pwa npm i next-pwa配置next.config.js const path require(path);const withPWAInit require(next-pwa);// 判断…

企业数据安全管理容易忽视的关键点:云存储权限管控

云存储已经广泛应用于企业用户、教育领域、医疗领域以及政府和公共服务部门。具体应用场景包括文件共享、数据备份、在线课程、教学资源库、电子病历、医学影像、实验室数据、政务数据的集中管理和共享等。 云存储的优势非常明显&#xff1a; 可扩展性&#xff1a;云存储空间可…

NextJs 数据篇 - 数据获取 | 缓存 | Server Actions

NextJs 数据篇 - 数据获取 | 缓存 | Server Actions 前言一. 数据获取 fetch1.1 缓存 caching① 服务端组件使用fetch② 路由处理器 GET 请求使用fetch 1.2 重新验证 revalidating① 基于时间的重新验证② 按需重新验证revalidatePathrevalidateTag 1.3 缓存的退出方式 二. Ser…

【遂愿赠书 - 2期】:618火热来袭,网络安全书单推荐

文章目录 一、网络安全书单背景二、网络安全与编程实践书单2.1 &#x1f3f0;《内网渗透实战攻略》2.2 &#x1f6e1;️《Kali Linux高级渗透测试&#xff08;原书第4版&#xff09;》2.3 &#x1f396;️《CTF那些事儿》2.4 &#x1f680;《权限提升技术&#xff1a;攻防实战与…

MT2085 小码哥的福利

思路&#xff1a; 1. 耐受度从小到大排序&#xff0c;每一个甜品都找到第一个能忍受其甜度的手下。 例如样例&#xff1a;甜度为1的2份甜品给第1个人吃&#xff08;此人耐受为2&#xff09;&#xff1b;甜度为3的9份甜品给第2个人吃&#xff08;此人耐受为3&#xff09;&…

学习串口屏需要了解哪些方面的知识

学习串口屏需要掌握的知识主要包括以下几个方面&#xff1a; 串口通信原理&#xff1a;串口屏是基于串口通信的显示控制模组&#xff0c;因此了解串口通信的基本原理和通信协议是必要的。你需要了解串口通信的基本概念、数据格式、波特率、校验位等参数&#xff0c;以及串口通…

python嵌套列表求学生平均分

嵌套列表 3个学生&#xff0c;5门课程&#xff0c;求每门课程的平均分和最大最小分 import randomnames [张三, 李四, 王五] courses [语文, 数学, 英语, 体育, 科学] # 嵌套列表&#xff0c;scores [[74, 96, 51, 83, 77], [81, 75, 75, 77, 52], [66, 57, 56, 74, 95]] s…

在iPad上恢复丢失数据的3方法

iPad概览 iPad不仅可以用来看电影&#xff0c;还可以用来工作和学习。使用 Apple Pencil&#xff0c;您可以在 iPad 上做笔记、画画、制作音乐、编辑视频和在课堂上教学等。同时&#xff0c;由于体积小&#xff0c;您可以在商务旅行中轻松随身携带。因此&#xff0c;iPad已成为…

Spring-IoC入门案例

黑马程序员SSM框架教程 文章目录 一、创建一个项目1.1 新建项目1.2 创建dao和service包&#xff0c;项目结构如下1.3 代码1.4 运行结果 二、将service和dao交给IoC容器管理2.1 导入Spring的坐标spring-context&#xff0c;对应版本是5.2.10.RELEASE2.2 2. 配置bean2.3 获取IoC容…

使用matplotlib.animation.ArtistAnimation绘制摆线

在数学中&#xff0c;摆线&#xff08;Cycloid&#xff09;被定义为&#xff0c;一个圆在一条直线上滚动时&#xff0c;圆边界上一定点所形成的轨迹。它是一般旋轮线的一种。摆线亦称圆滚线。 摆线也是最速降线问题和等时降落问题的解。 应用matplotlib.animation.ArtistAnimat…

BUG记录——代码正确,free报错

项目场景 无具体场景&#xff0c;学习数据结构时发现的问题。 问题描述 malloc后无法释放空间&#xff0c;报错显示如下。 图中代码如下。 int main() {int* a (int*)malloc(sizeof(int));free(a);return 0; } 原因分析 我使用的是VisualStdio2022版本&#xff0c;头文件的需求…

vscode设置编辑器文件自动保存

步骤 1.打开vscode的设置 2.在搜索栏输入关键字“保存”&#xff1b; 在 Files: Auto Save 设置项&#xff0c;选择自动保存的模式

echarts 交错柱状图, 对向柱状图, 双柱状图横向

设计图样式 上代码 父组件 <bar-chart :option"energyOption"></bar-chart>initChart() {//上周能耗排行榜this.black_label ["漫张农污处理设施","邓庄农污处理设施","王桥农污处理设施","甲庄农污处理设施"…

充电宝如何选购?2024年全网充电宝选购大全!选充电宝注意这几点

在2024年的数字生活浪潮中&#xff0c;充电宝虽小&#xff0c;却是维系我们设备活力的关键。但市面上产品良莠不齐&#xff0c;安全问题频发&#xff0c;如何从中筛选出既安全又实用的充电宝&#xff0c;成为每位数码达人的必修课。别担心&#xff0c;这篇“充电宝如何选购&…

leetcode第867题:转置矩阵

matrix[i][j]需要放在转置矩阵的(j,i)位置 public class Solution {public int[][] Transpose(int[][] matrix) {int rows matrix.Length; int columns matrix[0].Length; int[][] array2 new int[columns][];// 初始化内部数组&#xff08;列数&#xff09;for (int i 0…