【网络】传输层协议-UDP协议

news2025/1/17 5:57:06

文章目录

  • 传输层TCP/UDP
    • 预备知识:
      • 端口号的理解
        • 端口号的范围
      • 关于端口号的相关问题
      • netstat命令
      • pidof命令
  • UDP协议
    • 所处的位置
    • UDP协议格式
    • UDP的特点
    • UDP的缓冲区
      • 基于UDP的应用层协议

传输层TCP/UDP

回忆数据发送到网络的过程

之前在学习HTTP等应用层协议时为了方便理解:我们简单的认为HTTP协议是将请求和响应直接发送到了网络当中

实际上: 应用层需要先将数据交给传输层,由传输层对数据做进一步处理后再将数据继续向下进行交付,该过程贯穿整个网络协议栈,最终才能将数据发送到网络当中


传输层负责可靠性传输,确保数据能够可靠地传送到目标地址, 为了方便理解,在学习传输层协议时也可以简单的认为传输层协议是将数据直接发送到了网络当中


预备知识:

端口号的理解

  • 端口号(Port)标识一个主机上进行网络通信的不同的应用程序

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

  • 从网络中获取的数据在进行向上交付时,在传输层就会提取出该数据对应的目的端口号,进而确定该数据应该交付给当前主机上的哪一个服务进程
  • 端口号是属于传输层的概念的,在传输层协议的报头当中就会包含与端口相关的字段

在TCP/IP协议中用下面的五元组来标识一个唯一的通信:

组成解释
源IP+源端口号标识数据来源,来自互联网中的那台主机的那个进程
目的IP+目的端口号标识数据目的地,去往互联网中的那台主机的那个进程
协议号通信使用的是哪一个协议,向上交付给哪一个协议

具体步骤:

1)先提取出数据当中的目的IP地址和目的端口号,确定该数据是发送给哪个服务进程的

2)然后提取出数据当中的协议号,为该数据提供对应类型的服务

3)最后提取出数据当中的源IP地址和源端口号,将其作为响应数据的目的IP地址和目的端口号,将响应结果发送给对应的客户端进程


端口号的范围

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

  • 一些知名的服务绑定的端口一般是固定不可变的

    • 如:0 ~ 1023:知名端口号.比如HTTP,FTP,SSH等这些广为使用的应用层协议,它们的端口号都是固定的
      • ssh服务器,使用22端口 ftp服务器,使用21端口 telnet服务器,使用23端口 http服务器,使用80端口 https服务器,使用443端口
  • 1024 ~ 65535:操作系统动态分配的端口号.客户端程序的端口号就是由操作系统从这个范围分配的

    • 我们部署自身服务时,绑定1024-65536的端口即可

关于端口号的相关问题

协议号 VS 端口号

  • 协议号是存在于IP报头当中的,其长度是8位

    • 协议号指明了数据报所携带的数据是使用的何种协议,以便让目的主机的IP层知道应该将该数据交付给传输层的哪个协议进行处理.
  • 端口号是存在于UDP和TCP报头当中的,其长度是16位

    • 端口号的作用是唯一标识一台主机上的某个进程.

区别: 协议号是作用于传输层和网络层之间的,而端口号是作用于应用层于传输层之间的.


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

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

  • 我们之前写http代码的时候,就出现过bind error的错误,本质就是该端口号已经被绑定了

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

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


可以类比一颗多叉树:

image-20220912162654520


我们可以通过vim /etc/services查看知名端口号:

image-20220912155856595


netstat命令

netstat是一个用来查看网络状态的重要工具,通过netstat命令可以查看到上面的五元组信息

常见选项

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

查看TCP相关的网络信息时,一般选择使用nltp组合选项, 查看UDP相关的网络信息时,一般选择使用nlup组合选项

image-20220912160214645

Local Address表示的就是源IP地址和源端口号 Foreign Address表示的就是目的IP地址和目的端口号

Proto表示的就是协议类型,因为我们带了-t选项,所以显示的都是TCP协议通信的进程


pidof命令

pidof命令可以通过进程名,查看进程id.

使用方法:pidof 进程名称

小例子:我们用pidof命令查看我们自己编写的一个死循环进程,然后用kill名称杀死这个进程

image-20220912163611212


UDP协议

所处的位置

传输层协议在系统内核中之上是系统调用,再之上是具体的应用层协议.而UDP/TCP协议是在应用层(内核)中,所以UDP和TCP是对上提供接口的协议.

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

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

image-20220912210302804


不管是哪一层协议都需要思考两个问题:

1.如何进行封装和解包

  • 封装:就是添加上8字节的定长报头
  • 解包:就是将报头和有效载荷分离

2.如何分用,向上交付

所以我们来一下UDP协议的段格式:


UDP协议格式

UDP协议格式如下

image-20220912212521454

  • 16位源端口号:表示数据是从哪里来的
  • 16位目的端口号:表示数据要到哪里去,代表的是当这个报文被目标主机收到的时候,它会根据16位目的端口号交付给应用层的哪一个进程,其中会把数据交互给上层程序
  • 16位UDP长度:表示整个数据报(即报文 = UDP首部(报头)+UDP数据(有效载荷) )的长度
  • 16位UDP检验和:如果UDP报文的检验和出错,就会直接将报文丢弃

理解之前我们写http套接字的时候,为什么需要绑定端口号:

因为当底层收到了对应的UDP报文,他会根据报文的目的端口号把数据转给特定的绑定这个端口的进程

为什么端口号是16位

我们之前定义端口号都是这样定义的: uint16_t port = atoi(argv[1]),其中uint16_t代表的就是16位整形

我们在应用层看到的端口号大部分都是16位的,其根本原因就是因为传输层协议UDP报头当中的端口号就是16位的,这属于协议规定!


UDP如何将报头与有效载荷进行分离

1)UDP的报头当中只包含四个字段,每个字段的长度都是16位,总共8字节.因此UDP采用的实际上是一种定长报头

2)UDP在读取报文时读取完前8个字节后剩下的就都是有效载荷了


UDP如何做到向上交付, 即: UDP如何决定将有效载荷交付给上层的哪一个协议

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

2)应用层的每一个网络进程都会绑定一个端口号,服务端进程必须显示绑定一个端口号,客户端进程则是由系统动态绑定的一个端口号

3)UDP就是通过报头当中的目的端口号交付有效载荷给应用层的对应进程

注意:

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


Linux kernel 是用C语言写的,如何看待UDP报头(报文)

注意: 报文 = 报头 + 有效载荷

操作系统是C语言写的,而UDP协议又是属于内核协议栈的,因此UDP协议也一定是用C语言编写的,UDP报头实际就是一个位段类型

struct udp_hdr
{
  uint32_t src_port: 16; //源端口号-16位
  uint32_t dst_port: 16; //目的端口号-16位
  uint32_t total: 16;	//UDP长度-16位
  uint32_t check: 16;	//UDP检验和-16位
};

UDP数据封装:

当应用层将数据交给传输层后:

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

UDP数据分用:

当传输层从下层获取到一个报文后:

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

UDP的特点

udp的通信过程类似于寄信.

  • 无连接:知道对端的IP和端口号就直接进行传输,不需要建立连接.

  • 不可靠:没用确认和重传机制

    • 如果因为网络故障或者其它问题导致报文无法发到对方,UDP协议不会返给上层任何数据丢失或接收成功的信息.
  • 面向数据报:不能灵活地控制写入获取报文中数据的次数和数量

    什么是面向数据报?

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

    • 即: 接收数据时只能按报文的大小一次性将报文全部收取上来

      例子:发送端假如一次调用sendto发送了100个字节,接收端也必须一次性recvfrom将100个字节全部提取出来,所以在网络看来,在双端主机看来, 我们拿到的都是一个一个独立的报文


UDP使用注意事项

UDP报头中用16位UDP长度来表示整个报头的长度

  • 所以UDP最大只有65536个字节(2^16), 因此一个UDP报文的最大长度是64K(UDP报头+有效载荷)
  • 如果非要使用UDP发送超过64KB长度的数据包,只能拆包发送,并且对端按序号再将数据包整合到一起

注意: 报文在网络中进行路由转发时,并不是每一个报文选择的路由路径都是一样的,因此报文发送的顺序和接收的顺序可能是不同的


UDP的缓冲区

首先,我们要知道: 网络套接字收发接口read/write/recv/send,虽名为读取,发送函数,但实质我们更愿意称之为拷贝函数, 因为这些接口并不是将数据直接发送到网络中,而是将数据从应用层拷贝到传输层的收发缓冲区中

拷贝完成之后,这些网络接口的工作就完成了.具体该数据什么时候发,一次发多少,发送失败怎么办,完全由OS内核中的传输层控制.这就是传输层的任务:提供传输数据的策略

例如:

1)当调用读取函数的时候,并不是把数据直接从网络里读上来,而是把数据从传输层的TCP的接收缓冲区/UDP的接收缓冲区里拷贝到用户空间

  • UDP只有接收缓冲区,没有发送缓冲区 TCP有接收缓冲区&&发送缓冲区

2)当我们写入函数的时候,并不是把数据直接发到网络中,而是把数据拷贝到TCP的发送缓冲区当中,然后再往后处理

image-20220912215124644
  • UDP没有真正意义上的发送缓冲区.调用sendto函数会直接把数据交给内核,由内核将数据传给网络层协议进行后续的传输动作
  • UDP具有接收缓冲区.接收到的数据存放在接收缓冲区中,以待上层调用接收函数, 但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致
    • 如果UDP的接收缓冲区满了,再到达的UDP数据就会被丢弃
  • UDP是全双工的
    • 全双工就是双方的收发互不影响,可以同时进行收发,同时调用收发函数
    • 半双工就是双方不能同时进行收发,一方在发对方就不能发只能收,反之同理

问题:为什么UDP要有接收缓冲区

1)如果UDP没有接收缓冲区,那么就要求上层及时将UDP获取到的报文读取上去

  • 如果一个报文在UDP没有被读取(上层没有调用读取函数),此时UDP从底层获取上来的报文数据就会被迫丢弃

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

3)因此UDP本身是会维护一个接收缓冲区的,

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

缓冲区存在的价值:

一方面:让传输层定制传输数据的策略,另一方面,它将应用层协议和下层的通信细节,进行了解耦!

1)上层只要把数据拷贝到缓冲区,因为传输层属于协议栈,在OS启动之后就在内核,也就是在内存里面,所以说白了就是把数据从内存拷贝到内存,效率很高,

2)接下来数据怎么发送,要经过网络,比较费时间,所以只要能正常拷贝,拷贝之后,上层立马返回,可以直接进行后序处理,而发送的细节就由OS帮我们进行


基于UDP的应用层协议

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

当然,我们自己写UDP程序时自定义的应用层协议也属于这个范畴


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

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

相关文章

液晶显示控制驱动器HD61202介绍

液晶显示控制驱动器HD61202的特点 HD61202液晶显示控制驱动器是一种带有驱动输出的图形液晶显示控制器,它可直接与8位微处理器相连,它可与HD61203配合对液晶屏进行行、列驱动。HD61202是一种带有列驱动输出的液晶显示控制器,它可与行驱动器HD…

Docker 进阶实战:数据管理、网络

文章目录 Docker 进阶实战:数据管理、网络数据管理Volume创建数据卷挂载数据卷共享数据卷删除数据卷 Bind mountstmpfs mounts 网络端口映射容器互联Docker 内部网络Docker linkDocker Networking Docker 进阶实战:数据管理、网络 数据管理 默认情况下…

基于simulink使用麦克风阵列的声波束成形

一、前言 此示例演示如何对麦克风阵列接收到的信号进行波束化,以在嘈杂环境中提取所需的语音信号。 二、模型的结构 该模型模拟在 10 元件均匀线性麦克风阵列 (ULA) 上接收来自不同方向的三个音频信号。在接收器处添加热噪声后,应…

如何利用 Playwright 对已打开的浏览器进行爬虫!

大家好,我是安果! 之前写过一篇关于如何利用 Selenium 操作已经打开的浏览器进行爬虫的文章 如何利用 Selenium 对已打开的浏览器进行爬虫! 最近发现很多人都开始摒弃 Selenium,全面拥抱 Playwright 了,那如何利用 Pla…

经典文献阅读之--Point-LIO(鲁棒高带宽激光惯性里程计)

0. 简介 在我们之前接触的算法中,基本上都是要处理帧间雷达畸变的,类似于VSLAM系统,频率固定(例如10Hz), 而实际上,激光雷达点是按照不同的时间瞬间顺序采样的,将这些点累积到帧中会引入人工运动畸变&…

3_机器学习数学基础知识

文章目录 一、偏导数二、目标函数(损失函数)求解方法2.1 梯度下降法2.2 坐标轴下降法2.2.1 坐标轴下降法算法公式2.2.2 坐标轴下降法算法过程 2.3 坐标轴下降法和梯度下降法的区别 三、概率3.1 大数定律、中心极限定理3.2 最大似然函数3.3 概率知识3.3.1…

windows下python下载及安装

下载python安装包 进入python官网:https://www.python.org/ 鼠标移动到“Downloads”->"Windows"上,可以看到最新版本是3.11.3版本 点击“Windows”按钮,可以去下载其他版本 标记为embeddable package的表示嵌入式版本&#x…

MyBatis:使用到的代码整理

文章目录 MyBatis:Day 04框架1. 依赖:pom.xml2. 外部配置文件:db.properties3. 核心配置文件:mybatis-config.xml4. 工具类:MybatisUtils.java5. 实体类6. 接口:xxxMapper.java7. 实现类:xxxMap…

[数据库系统] 三、简单查询

目录 第1关:简单查询 1.检索数据表所有的元组 2.检索符合条件的元组 educoder 第2关:多表查询 1.笛卡尔积 2.等值连接 3.自然连接 4.左外连接和右外连接的表示方法及转换为SQL educode 第3关:集合操作 1.集合并操作 2.集合交操作…

小学生护眼用什么样的台灯比较好用一点?小学生护眼台灯排行榜

孩子近视了,很多家长认为是数码产品导致的。其实除了数码产品,灯光也是一个非常重要的原因。或许你认为卧室的灯亮孩子写作业就没有问题,其实这种情况仍会出现灯下黑的现象。如果你想孩子写作业不受灯光的影响,那么一定要给他们配…

实验四 数据库设计

【实验目的】 1、掌握规范化数据库设计包括步骤及其任务、方法、结果等。 2、掌握数据库设计过程中关键文档的写法。 3、了解数据库辅助设计工具。 【实验内容】 请按下面大纲书写实验报告(请自行附页)。 (1)需求分析&#…

【MySQL】Mysql索引失效场景(15个必知)

文章目录 背景数据库及索引准备创建表结构初始化数据数据库版本及执行计划 1、联合索引不满足最左匹配原则2、 使用了select *3 、索引列参与运算4、 索引列参使用了函数5、 错误的Like使用6、 类型隐式转换7、使用OR操作8、 两列做比较9、 不等于比较10、 is not null11、 not…

ChatGPT实现stackoverflow 解释

stackoverflow 解释 ChatGPT 公开服务以来,程序员们无疑是最早深入体验和"测试"的一批人。出色的效果也引发了一系列知识产权上的争议。著名的 stackoverflow 网站,就宣布禁止用户使用 ChatGPT 生成的内容来回答问题,一经发现&…

系统分析师之系统设计(十五)

目录 一、软件流程设计 1.1 业务流程分析方法 1.2 业务流程建模 1.2.1 标杆瞄准 1.2.2 IDEF 1.2.3 DEMO 1.2.4 流程建模语言 1.2.5 基于服务的BPM 1.2.6 业务流程重组BPR 1.2.7 业务流程管理BPM 二、软件架构设计 2.1 概念 2.2 软件架构风格 三、 结构化设计 四…

这样的应急科普,你爱了吗?

“当我给救援队叔叔系上红领巾的时候,我特别的自豪,很开心!” “救援队的叔叔、阿姨们都很伟大,我长大了,也想和他们一样。” “我爸爸就是一名救援队队员,我很崇拜他!” 敬少先队员礼&#…

高通 Android 8/9/12/13 兼容U盘识别extfat模式

Android本身不支持extfat格式 需要通过nofuse 打kernel补丁方式去实现 Android 8/9 1、kernel/msm-4.9/arch/arm64/configs/sdm670-perf_defconfig 增加代码如下(需要提交编译kernel记得git add sdm670-perf_defconfig 不需要commit哈!否则编译会还原…

最强算法视频公开课!(内容硬核,完全免费!

和录友们汇报一下,代码随想录算法公开课已经更新完毕了。 由我亲自录制了140期算法视频,覆盖了 《代码随想录》纸质版上全部题目的讲解。 视频全部免费开放在B站:代码随想录 目录就在视频播放的右边,完全按照代码随想录的顺序讲…

利用Redis的SetNx一步步实现分布式锁并改进

文章目录 1 基本原理和实现方式对比2 Redis分布式锁的实现核心思路3 利用setnx方法实现分布式锁加锁逻辑释放锁逻辑修改业务代码 4 Redis分布式锁误删情况说明5 解决Redis分布式锁误删问题6 分布式锁的原子性问题7 Lua脚本解决多条命令原子性问题8 利用Java代码调用Lua脚本改造…

DevOps产品开发实践

背景 2022年11月,公司启动了智能运维产品的研发项目,该项目基于zabbix进行二次开发,对行业客户的数据中心的基础软硬件设施进行数据采集和分析,通过持续的数据采集和监控,及时发现数据中心软硬件的异常状态并预警&…

k8s集群部署 | 三节点(复用)高可用集群过程参考

文章目录 1. kubeadm 部署三节点(复用)高可用 k8s 集群1.1 环境规划阶段1.1.1 实验架构图1.1.2 系统版本说明1.1.3 环境基本信息1.1.4 k8s 网段划分 1.2 基础安装及优化阶段1.2.1 系统信息检查1.2.2 静态 IP 地址配置1.2.3 配置主机名1.2.4 配置/etc/hos…