【传输层协议】UDP协议 {端口号的范围划分;UDP数据报格式;UDP协议的特点;UDP的缓冲区;基于UDP的应用层协议}

news2024/10/2 10:40:22

一、再谈端口号

1.1 端口号标识网络进程

如何通过端口号找到主机上的网络进程?

  1. 在socket编程中bind绑定是最为重要的一步:
  2. 他将套接字与指定的本地 IP 地址和端口号关联起来,这意味着指定的套接字可以接收来自指定 IP 地址和端口号的数据包。
  3. 同时系统也会为端口号与进程pcb指针建立映射关系,这意味着通过端口号就可以找到与之关联的进程。

1.2 使用“五元组”标识一个通信

在这里插入图片描述

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

在TCP/IP协议中, 用 “源IP”, “源端口号”, “目的IP”, “目的端口号”, “协议号” 这样一个五元组来标识一个通信(可以通过netstat -n查看);

netstat 查看网络状态的重要工具


1.3 端口号的范围划分

在这里插入图片描述

  • 0 - 1023:这个范围内的端口号被保留用于一些特定的服务和应用程序,称为“系统端口”或“熟知端口”Well-Know Port Number)。例如:HTTP, FTP, SSH等这些广为使用的应用层协议, 他们的端口号都是固定的。系统一般不允许用户自己绑定这个范围内的端口号。
  • 1024 - 65535:这个范围内的端口号大多数是可以自由绑定的,但也有个别例外,比如mysql绑定3306号端口。除去这些例外,其他的端口号可以由用户显式bind绑定,也可以由操作系统动态分配(客户端端口号绑定)。

常用的熟知端口

有些服务器是非常常用的, 为了使用方便, 人们约定一些常用的服务器, 都是用以下这些固定的端口号:

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

提示:在/etc/services文件中可以查看到系统中所有的知名端口号。我们自己编写的程序使用端口号时, 要避开这些知名端口号.

两个问题

  1. 一个进程是否可以bind多个端口号?当然可以,一个进程可以从多个端口收发数据。
  2. 一个端口号是否可以被多个进程bind?不可以,端口号指向系统中唯一的一个进程。

介绍两个小工具:

  1. pidof <进程名>:通过进程命查看进程ID,在查看服务器的进程ID时非常方便。
  2. ... | xargs proc ...:xargs可以将前面命令行中管道文件的输出转换为之后程序的命令行参数。

打一套组合拳:

在这里插入图片描述


二、UDP协议

2.1 UDP数据报格式

UDP(User Datagram Protocol,用户数据报协议)是工作在OSI(开放系统互连,Open Systems Interconnection)模型中传输层的一种协议,使用IP作为底层协议。UDP协议的格式相对简单,主要由以下几个部分组成:

在这里插入图片描述

UDP数据报分为首部和用户数据部分,整个UDP数据报作为IP数据报的数据部分封装在IP数据报中。UDP数据报文结构包括:

  • 源端口号(Source Port):占用2个字节(16位),表示发送方端口号。在要求对方回信时选用,不要求时可使用全0。
  • 目的端口号(Destination Port):占用2个字节(16位),表示接收方端口号。在终点交付报文时必须使用。
  • 长度(Length):占用2个字节(16位),表示UDP数据报的长度,包括首部和数据部分。其标定的长度最小值是8B(只有首部),最大值是2^16 = 64KB。
  • 校验和(Checksum):占用2个字节(16位),用于检测UDP数据报在传输过程中是否有错误。如果检测到校验和出错,就会直接丢弃该报文。
  • 数据(Data):占用0个或多个字节,是实际传输的数据部分。

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

  • UDP采用定长报头,UDP在读取报文时读取完前8个字节后剩下的就都是有效载荷

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

  • UDP是通过报头当中的目的端口号来找到对应的应用层进程的,即由目的端口号决定。
  • 当UDP数据报到达时,操作系统会根据目的端口号找到相应的应用程序或服务,并将数据报交付给它进行处理

在Linux内核中数据报是怎样被封装和管理的?

在这里插入图片描述

  1. 首先Linux内核是使用C语言编写的,那么UDP作为传输层协议(内核中)自然也是一样。

  2. 所以UDP报头结构在内核中其实就是一个结构体类型:

    在这里插入图片描述

  3. 所以当应用程调用sendto接口发送数据时,系统就会创建并填充UDP报头。

  4. sk_buff(socket buffer)结构是linux网络代码中重要的数据结构,它负责管理和控制接收或发送数据包的信息

  5. sk_buff结构其实就是对数据报的封装,将UDP协议的报头和数据内容封装成一份完整的数据报。

  6. sk_buff结构中包含prev和next指针,操作系统将所有进程发出的sk_buff通过链表组织到一起,按序发送到网络。

  7. 对端主机将接收到的数据存入新创建的sk_buff结构当中,并依据端口号将其分派给对应进程的UDP接收缓冲区。

  8. 客户端调用recvfrom接口从UDP缓冲区读取数据,得到源端口号和报文内容。

注意:sk_buff结构较为复杂,上面的内容只是我片面的理解,甚至可能存在错误。

详情请阅读:Linux内核:sk_buff解析 - 唐稚骅 - 博客园 (cnblogs.com)


2.2 UDP协议的特点

  • 无连接:UDP在发送数据前不进行连接,发送结束时也没有连接可以释放,减少了开销和发送数据之前的时延。
  • 不可靠:没有确认机制,没有重传机制,如果因为网络故障使该段无法发送到对方,UDP协议层也不会给应用层返回任何错误信息。也正是因为UDP不保证可靠交付,使得主机不必维持复杂的连接状态。
  • 面向报文:发送方的UDP对应用程序交下来的报文,再添加首部后就向下交付IP层。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。发送方发送了多少次数据报,接收方就需要接收多少次,不能一次性合并接收,也不存在接收到不完整的数据报。
  • 无拥塞控制:很多实时应用(如IP电话、实时视频会议等)要求源主机以恒定的速率发送数据,并且允许网络发生拥塞时丢失一些数据,却不允许数据有太大的时延,UDP正好适合这种要求。
  • 首部开销小:UDP只有8个字节的首部,适用于对时间敏感、但对可靠性要求不高的应用场景。
  • 全双工通信:虽然UDP没有发送缓冲区,但是UDP的socket既能读,也能写,所以也是全双工通信协议。

综上所述,UDP协议的格式简单,开销小,适用于对实时性要求较高但对可靠性要求不高的应用场景。

面向数据报

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

  • 可以想像成快递:你朋友给你发了1个快递,你就只能收1个快递,你不能只收0.5个快递,也不能收2个快递,你只能收1个,即发多少就收多少。

  • UDP发送的数据不能太大,UDP的报文最大长度是64KB(UDP首部+UDP数据)

  • 如果需要传输的数据超过64K,就需要在应用层进行手动分包,多次发送,并在接收端进行手动拼装。


2.3 UDP的缓冲区

  • UDP没有真正意义上的发送缓冲区。调用sendto会直接交给内核,由内核将数据传给网络层协议进行后续的传输动作。
  • UDP具有接收缓冲区。但是这个接收缓冲区不能保证UDP数据报的接收顺序和发送顺序一致;如果缓冲区满了,再到达的UDP数据报就会被丢弃。

为什么UDP没有发送缓冲区

  • 因为不需要,UDP协议的设计目标是提供一种简单的、无连接的通信方式。
  • UDP协议的设计初衷是为了实现高效的数据传输,尽量减少协议本身的开销。不提供可靠性和流量控制的机制,因此不需要发送缓冲区
  • 调用sendto会把数据直接交给内核,由内核将数据传给网络层协议进行后续的传输动作。

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

虽然 UDP 是一种无连接的、不可靠的传输协议,但仍然需要接收缓冲区来暂时存储接收到的 UDP 数据包。以下是几个理由:

  1. 数据处理速度不匹配:发送端的数据处理速度可能快于接收端的数据处理速度。如果没有接收缓冲区,接收端处理数据的速度跟不上发送端发送数据的速度,可能导致数据包在传输过程中被丢弃或溢出。通过接收缓冲区,接收端可以临时存储尚未处理的数据包,以便之后逐个处理。

  2. 数据包乱序、丢失处理:由于 UDP 协议本身不提供拥塞控制和重传机制,可能会导致数据包乱序到达或部分数据包丢失。接收缓冲区可以暂时保存乱序到达的数据包,并允许应用程序按顺序处理数据。此外,接收缓冲区还可以让应用程序检查是否丢失了某些数据包,并采取适当的措施。

  3. 简化应用程序设计:即使 UDP 是一种简单的协议,但应用程序仍需要一定的缓冲区来存储接收的数据。接收缓冲区的存在可以简化应用程序设计,让应用程序不需要关心接收时的数据处理细节,只需从缓冲区中读取数据即可。

总之,虽然 UDP 协议不提供可靠性保证,但接收缓冲区仍然是必要的,用于在一定程度上处理乱序到达、丢包等情况,并为应用程序提供一个暂存数据的地方,以便后续处理。


三、基于UDP的应用层协议

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

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

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

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

相关文章

跟李沐学AI:转置卷积

定义 卷积不会增大输入的高宽&#xff0c;通常卷积层后高宽不变或减半。转置卷积则可以用来增大输入的宽高。 转置卷积是一种卷积&#xff0c;它将输入和核进行了重新排列&#xff0c;通常用作上采用。 如果卷积将输入从变为&#xff0c;同样超参数的情况下&#xff0c;转置…

坐标大连!提交EI、Scopus、知网检索!第五届经济管理与大数据应用国际学术会议(ICEMBDA 2024)

合作ACM出版-EI稳检索 高录用&#xff0c;快见刊&#xff01; 管理、经济、金融、计算机相关主题均可投稿 目前仍有口头汇报名额&#xff0c;如有需要请尽快报名 重要信息 会议官网&#xff1a;www.icembda.org 会议时间&#xff1a;2024年10月25日-27日 会议地点&#x…

20.缓存的更新策略

定义 缓存中的旧数据与数据库不一致。 缓存更新策略的类型 1.内存淘汰&#xff0c;利用redis的内存淘汰机制&#xff0c;当内存不足时自动淘汰部分数据。下次查询时更新缓存。redis默认开启了此机制。这种保证数据的一致性差。 2.超时剔除&#xff0c;给缓存数据添加TTL时间…

保证MQ的高可用性:RabbitMQ为例

保证MQ的高可用性&#xff1a;RabbitMQ为例 一、单机模式二、普通集群模式三、镜像集群模式 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 消息队列&#xff08;MQ&#xff09;在软件开发中至关重要&#xff0c;其高可用性关乎系统稳定。R…

48、Python之模块和包:当导入模块时,Python解释器做了什么

引言 上一篇文章中&#xff0c;我们简单介绍了各种导入模块的方法&#xff0c;并通过代码演示了模块被导入之前的模块查找的路径解析过程&#xff0c;但是&#xff0c;只是局限在了加载模块之前。 今天这篇文章&#xff0c;打算把整个模块导入的全流程进行梳理&#xff0c;从…

Windows上传Linux文件行尾符转换

Windows上传Linux文件行尾符转换 1、Windows与Linux文件行尾符2、Windows与Linux文件格式转换 1、Windows与Linux文件行尾符 众所周知&#xff0c;Windows、Mac与Linux三种系统的文件行尾符不同&#xff0c;其中 Windows文件行尾符&#xff08;\r\n&#xff09;&#xff1a; L…

【初阶数据结构题目】40. 计数排序

计数排序 计数排序又称为鸽巢原理&#xff0c;是对哈希直接定址法的变形应用。 操作步骤&#xff1a; 统计相同元素出现次数 根据统计的结果将序列回收到原来的序列中 思路&#xff1a; 例如&#xff1a;{6&#xff0c;1&#xff0c;2&#xff0c;9&#xff0c;4&#xff0c;…

书生模型实战L1---OpenCompass 评测

书生模型实战系列文章目录 第一章 入门岛L0&#xff08;Linux&#xff09; 第二章 入门岛L0&#xff08;python&#xff09; 第三章 入门岛L0&#xff08;Git&#xff09; 第四章 基础岛L1&#xff08;书生全链路开源介绍&#xff09; 第五章 基础岛L1&#xff08;Demo&#x…

【计算机三级-数据库技术】操作题大题(第六套)

第六套操作题 第46题 假定要建立一个学校科研项目管理的信息系统&#xff0c;需要管理如下信息&#xff1a; 教师&#xff1a;教师编号、教师姓名&#xff1b; 项目&#xff1a;项目编号、项目名称、资助额&#xff1a; 学生&#xff1a;学生编号、学生姓名、学位&#xff0c…

Spring底层机制环境搭建

文章目录 1.模块创建和依赖引入1.聚合模块&#xff0c;下面有一个myspring2.查看父模块是否管理了子模块3.myspring模块引入基本包 2.进行环境搭建1.目录概览2.UserController.java3.UserService.java4.UserDao.java5.AppMain.java6.beans.xml7.测试8.配置UserController.java为…

教程3_单元层次结构1

单元层次结构是指通过将多个单元嵌套使用&#xff0c;形成具有层次结构的设计。每个单元可以包含其他单元的实例&#xff0c;这些实例称为“子单元”&#xff0c;而包含这些子单元的单元称为“父单元”。这种结构使得复杂设计变得模块化和可复用。 1、创建并使用单元实例 创建…

解读电子看板如何助力线缆行业目视化改革

线缆行业作为国民经济的重要组成部分&#xff0c;其生产过程复杂&#xff0c;环节众多&#xff0c;对生产效率和质量控制有着严格的要求。传统的管理方式往往难以满足现代化生产的需求&#xff0c;而电子看板的引入&#xff0c;为线缆行业带来了全新的管理理念和模式&#xff0…

23.合并K个升序链表-----力扣

一、题目&#xff1a; 给你一个链表数组&#xff0c;每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中&#xff0c;返回合并后的链表。 题目链接 二、示例&#xff1a; 输入&#xff1a;lists [[1,4,5],[1,3,4],[2,6]] 输出&#xff1a;[1,1,2,3,4,4,5,6] 解释…

​元宇宙虚拟展厅如何搭建?制作​线上虚拟展厅的成本

电子商务热潮的日益普及&#xff0c;让更多企业开始寻找具有创新性的方式来向客户展示他们的产品和服务。而元宇宙中的虚拟展厅也为企业提供了一个独特的机会&#xff0c;作为帮助企业展示其产品和服务特色的平台&#xff0c;元宇宙越发地受欢迎。不过在元宇宙中制作虚拟展厅的…

自带灭火电池?深蓝SL03托底事故揭秘

近日&#xff0c;网络上的一段热传视频&#xff0c;让不少网友看得先是惊心动魄&#xff0c;然后却又啧啧称奇。 该视频显示&#xff0c;8月18日晚上19点28分&#xff0c;一辆深蓝SL03在行驶中意外遭遇严重托底事故&#xff0c;车辆瞬间腾空跳跃&#xff0c;紧接着底盘出现明火…

【状态模式】设计模式系列:理解与实践(详细解读)

文章目录 状态模式详解&#xff1a;理解与实践1. 引言2. 状态模式简介2.1 定义2.2 应用场景2.3 与其他模式的关系 3. 状态模式的基本概念3.1 上下文(Context)类的角色3.2 状态(State)接口/抽象类3.3 具体状态(Concrete State)类3.4 UML类图和时序图 4. 状态模式的工作原理4.1 如…

用Python解决预测问题_多元线性回归模板

多元线性回归是一种统计学方法&#xff0c;用于分析两个或多个自变量&#xff08;解释变量&#xff09;与一个因变量&#xff08;响应变量&#xff09;之间的关系。在最简单的线性回归模型中&#xff0c;只有一个自变量和一个因变量&#xff0c;它们之间的关系可以用一条直线来…

Java对象的内存结构

文章目录 概述1. 对象头 (Header)Mark Word1. 32位HotSpot虚拟机中的MarkWord2. 64位HotSpot虚拟机中的MarkWord Class PointerArray Length指针压缩原理指针压缩测试 2. 实例数据 (Instance Data)3. 填充数据 (Padding Data) 查看 Java 对象的内存结构使用反射和VisualVM、JCo…

linux下的oracle启动命令

一、服务器断电后&#xff0c;手工启动oracle数据库步骤如下&#xff1a; 1、进入数据库服务器&#xff0c;切换到oracle用户,命令&#xff1a;su - oracle 2、启动数据库&#xff0c;命令&#xff1a; 1&#xff09; sqlplus / as sysdba 2) startup 3&#xff09;如果数据库已…

Rabbit mq 虚拟机stop无法重启

之前从后台进去&#xff0c;这个地方死活无法重启 然后重启docker 以及mq都不行 docker exec -it <CONTAINER_ID_OR_NAME> /bin/bash rabbitmqctl stop_app rabbitmqctl start_app 最后删除虚拟机&#xff0c;然后重建就行了 rabbitmqctl delete_vhost / rabbitmqctl…