JavaEE-传输层协议

ops/2024/9/20 7:23:46/ 标签: java-ee, tcp, 网络协议

目录

一、UDP协议

二、TCP协议

TCP报文结构

TCP十大核心机制

确认应答

超时重传

接收缓冲区

连接管理

建立连接

断开连接


一、UDP协议

学习一个网络协议首先要学习报文结构

对于UDP协议来说,应用层数据到达UDP后就会给应用层数据加上UDP报头。

(UDP数据报 = 报头 + 载荷)

这是UDP报头格式:

 

16位源端口号和16位目的端口号就是发送方的端口号与接收方的端口号;

16位UDP长度:整个UDP数据报占多少长度,16bit是两个字节,能存储的数据范围是0~65535也就是 64kb,所以整个UDP数据报最多占64kb,减掉报头占的八个字节得出载荷(数据)可以占64kb-8字节的容量。

正因如此使用UDP开发程序就会受到很大制约,每次传输的数据报不能超过64kb

16位检验和(checksum):数据在传输过程中是可能出错的,比如比特翻转/丢包比特翻转是指你传输的数据本来是0结果到了对端变成了1,就需要有一些办法对传输的数据进行校验:(1)能够发现是否出错 (2)能够发现哪位出了错并且进行纠正。第一种办法代价较小,第二种办法消耗的时间空间更多,以上两种办法本质上都是引入冗余信息

在UDP中校验只能做到第一种的程度。

校验和通过引入冗余信息来校验传输的数据是否正确,拿着数据的一部分进行计算得到结果,拿着结果去比较,如果传输过程中数据发生变化那么结果也会发生变化,比对时接收方发现校验和不一致就会将这组数据丢弃

UDP中使用CRC算法计算校验和CRC的计算方式简单粗暴:设定两个字节的变量,把数据的每个字节取出来在这上面累加,如果结果溢出超出两个字节就把溢出部分舍弃。

这里计算校验和不是为了进行算术运算/得到准确的值,而是为了让每个字节都参与进来影响结果,不关心具体数值多少,只关心接收方从网络接收的校验和与自己算的是否相同

UDP现在的主要场景是对于性能要求高但对于可靠性要求不高的场景,比如分布式系统中多个服务器之间进行通信,网络结构简单&带宽充裕

二、TCP协议

TCP的特性:有连接、可靠传输、面向字节流、全双工;可靠传输是TCP最核心的机制,而这样的机制在代码是无法直观看到的。

TCP报文结构

首先介绍TCP的报头结构:

先介绍比较容易理解的

1、源端口/目的端口:发送方的端口号与接收方的端口号

2、4位头部长度:是指报头的长度

3、选项(optional):英文翻译过来是可选的,也就是可以加也可以不加。头部长度是4bit也就是能表示的数据范围是0~15,此处头部长度单位是4字节,再乘4之后能表示的数据范围就是0~60,最大数据长度就是60字节,去掉固定的20字节得出选项最多40字节;结论:如果选项没有,tcp报头最大长度是20字节,如果选项有,报头最大长度就是60字节。

4、六位保留:UDP的报文长度使用两个字节来表示太小了,所以在TCP报文里提前申请好一块空间先不用,但是以后说不定能用上,这个空间就叫保留位。

万一未来某一天TCP需要扩展一些新功能就用这个保留位来表示。

5、TCP报文中的六个标志位(SAFURP):TCP的灵魂,文章后面会依次提到,具体展开看是

6、16位检验和:此处检验和与UDP中的作用是一样的

TCP十大核心机制

确认应答

对于TCP协议来说要解决一个很严重的问题——可靠传输,所谓可靠传输,不是发送方的数据百分百传输到接收方,而是尽可能的让发送方知道数据是否传输到接收方

比如说班级里发送了一条通知,同学们都要回复一条收到,这条收到就是用来应答班级发出的请求,这样用于应答的数据报文称为应答报文,也就是标志位中ACK。

上述单纯的应答在批量发送数据时就会产生麻烦,在网络传输中经常会发生一个情况——后发先至按照上述的栗子也就是班级群先发了一条明天放假的通知,又发了一条明天有没有同学想来做志愿者的通知,你按照顺序回复收到和不想,而发送出去的应答报文则是不想先到,收到后到,就变成了你不想放假你想做志愿者;

后发先至是网络中客观存在不可以改变的。解决这个问题的办法就是:给传输的数据进行编号,应答的数据编号与传输的数据编号能够对应起来,即使出现后发先至也不影响对于传输数据的理解。

7、32位序号/32位确认序号:给应答报文使用(ACK为1才有效),根据确认序号就可以知道应答的哪条报文。

实际TCP序号不是按照一条两条的方式来进行编号,而是按照字节来编号,每个字节都会分配一个序号;假如说TCP载荷中存储了1000字节的数据,每个字节都有编号而且顺序是递增的,假如说第一个字节的编号是1,那么第1000字节的编号就是1000,此时TCP报头中存储的编号是载荷中第一个字节的编号,此处存储的也就是1。(由于递增的特点,知道第一个字节的序号就可以知道后面的所有序号)

确认序号的设计也很有特点,确认序号是载荷中最后一个字节的编号+1;此处可以理解成:A向B发送了载荷1000字节编号1~1000的数据包,B应答给A一个确认序号是1001的应答报文,对于B来说<1001的字节都已经收到了,对于A来说可以继续发送1001~2000的数据了

(发送方发送的数据包只有序号字段有效,确认字段无效;接收方返回的ACK只有确认字段有效

TCP最核心的功能就是可靠传输,可靠传输主要依靠确认应答机制,通过应答报文告诉发送方数据的传输情况,如果当数据的传输没那么顺利就会出现丢包的情况,TCP的另一个核心机制——超时重传,来解决丢包问题。

(丢包:数据传输过程中被丢弃了无法传送至对端,也是客观存在的随机现象;丢包出现的原因:每个路由器/交换机的转发能力存在上限,如果要转发的数据量超出自身的极限,多出的部分就会被丢弃)

超时重传

用来应对网络出现丢包情况的策略

正常情况下,TCP通过ACK确认应答报文来判断数据是否顺利到达,如果在传输过程中出现丢包情况,接收方就收不到数据也就不会给发送方发送确认应答。正常发送方发送完数据要等待一段时间才能收到ACK,如果等待时间超过了一定的阈值(超时),发送方就会认为发生了丢包的情况,此时就会把数据进行重传

这是数据丢了的情况下,那么ACK丢了呢?

这种情况下接收方正常接收数据返回ACK但是返回的ACK在传输过程中发生了丢包,此时发送方还是迟迟等不到ACK,等待时间超过了阈值后还是会进行超时重传,而此时接收方就会接收到两份一样的数据,这样的情况是非常不科学的:

TCP接收方会针对发来的数据按照序号进行去重,TCP层次上对于重复传输/重复接收无所谓,只要应用层读到的数据是不重复的就行,无论重传多少次内核都会保证应用层读到的数据是一份,此时可以确保应用程序不会因为重传而产生bug,核心的机制就是——去重

接收缓冲区

接收方的内核中存在一个数据结构——接收缓冲区(类似于阻塞队列)

这个过程是:A通过socket api操控内核给B的内核发送数据,B内核中进行去重后才会发给用户态。通过该图帮助理解

B拿到数据后层层分用(accept->clientSocket->InputStream->read),当进行到TCP这一层时就会有一个阻塞队列数据结构,将数据放到阻塞队列中,到read的时候就会将重复数据从内存缓冲区删掉

向内存缓冲区放数据的过程中会根据数据的序号在内存缓冲区中进行判断,如果存在/曾经存在过就会被直接丢弃。

此处也是生产者消费者模型,A是生产者,B是消费者,中间的内存缓冲区就起到了阻塞队列的作用。

接收缓冲区除了去重还有一个很重要的功能,针对收到的数据排序

网络传输过程中会出现后发先至,很多时候我们不希望的这样的情况发生想让我们发送出去的数据有序的到达接收方。虽然在传输过程中是后发先至的,在内存缓冲区针对数据的序号进行排序,小号在前面大号在后面,数据与数据间的序号是连续的

丢包本身就是一个小概率事件,假设丢包的概率是10%,那么重传的数据丢包的概率就是1%,如果连续几次重传都丢包说明丢包的概率相当大了,此时应该是网络出现了问题。

超时重传的时间是多少呢?

这个时间不是固定数值会动态变化,随着重传的轮次增加会逐渐变长;假设第一次等待时间是50ms触发超时重传,那么下一次就会等待100ms,如果还是没收到ACK就会等待更长的时间。

如果网络出现严重问题,重传多次多次还是无法收到ACK,达到一定次数阈值就会尝试重置连接

触发一个重置报文RST尝试重置连接,重置就是通信双方清空之前TCP传输的中间状态重新开始传输,网络出现严重故障时RST报文也是无法进行重新连接的,这样只能断开连接

正常重传后接收方会返回ACK确认应答,发送方收到ACK即可进行正常传输。

超时重传是确认应答的重要补充,TCP的可靠传输主要靠确认应答与超时重传的机制。

连接管理

建立连接:三次握手。 断开连接:四次挥手;

可以理解为两个机器一见面先进行打招呼,打招呼的过程中不进行实际上的数据交互是为进行打招呼而传输一些数据,握手与挥手过程中传输的网络数据包不携带任何与业务有关的数据

建立连接

通过三次交互让通信双方保存对方的信息。实现过程是:客户端给服务器发送一个SYN同步报文,服务器收到后返回ACK+SYN,客户端收到后再次返回ACK,此时成功建立连接:

客户端给服务器发送的数据报载荷是空着的只有报头,报头中的SYN标志位为1。

上述流程其实是四次交互,客户端给服务器发送同步报文为第一次交互,服务器收到同步报文后会先返回一个ACK确认应答,再服务器进行一系列操作后才会返回SYN,这是两次交互,而将这两个标志位合并为一个数据报发送可以提高效率,也就是在一个数据报中SYN和ACK标志位都为1。

三次握手的时候相当于让对方保存好自己的信息,保存好对方的信息(ip和端口)才算建立完成。

三次握手的意义及解决的问题

(1)三次握手相当于投石问路,在正式传输数据之前先确认一下通信链路是否畅通,也相当于保证TCP可靠传输的一种方式

(2)通过三次握手确认通信双方的接收和发送的功能是正常的

在交互过程中,步骤一执行完毕后B就会知道:A的发送功能是正常,B的接收功能是正常的;步骤二执行完后:A会知道A的发送功能/接收功能都是正常的,B的发送功能是正常的;步骤三执行完后:B会知道B的发送功能是正常的。此时正常的测试功能就完成了,可以进行交互了

(3)协商一些必要的参数:通过双方共同商量一些参数;TCP通信时使用的序号就是协商出来的,往往不是从0/1开始,而是通信双方一起协商出一个数字,第一次连接和第二次连接协商出的数字往往差别很大

TCP考虑到一个情况:“前朝的剑斩本朝的官”,也就是通信双方在进行若干次通信后断开再进行连接后,可能再这若干次通信过程中某个数据报走丢了造成发送方超出了等待时间进行了重传,而当这个数据报到达接收方时已经物是人非,现在已经是一个全新的连接,服务器收到这个数据报后会进行丢弃

如何区分当前收到的数据报是否是以前的连接产生的数据报?

通过序号就能分辨出来,每次建立连接都是一个全新的起始序号,如果收到一个数据报的序号与起始序号差别很大就可以当作是以前连接产生的数据报。

三次握手过程中TCP的状态:

Listen:服务器出现的状态,当服务器绑定端口成功后就会进入Listen状态,随时可以有客户端连接过来。

Established:建立完成,可以随时进行后续通信了。

断开连接

四次挥手中,双方都可以作为提出断开连接的一方先发送FIN结束报文

断开连接:通信双方将保存的对方的信息删除

假设这里先发出FIN结束报文的是客户端,客户端通过socket.close或者关闭进程等方式都可以发送结束报文。

四次挥手中间的两次挥手是否能合并?分情况

当服务器收到FIN后立即返回ACK,而返回FIN需要等服务器调用到close方法后才会返回,这两个操作可能会隔很久。

特殊情况下可以合并,TCP的机制——延时应答(不是立即回复ACK,而是等一会和FIN一起发送)

四次挥手期间的状态

CLOSE—WAIT:被动一方进入的状态,等待应用程序调用close方法,如果程序出现问题close没有被调用或者没有close方法就会导致机器上出现大量CLOSE_WAIT.

TIME—WAIT:存在意义是为了应对最后一个ACK丢包的情况:

刚才的情景中客户端向服务器发起FIN后,服务器先返回ack表示应答后在应用程序调用close返回FIN,此时服务器没有真正的删除对方的信息,而是要等待收到客户端返回的ACK才会正式删除对方的信息断开连接;如果最后一个ACK出现丢包的情况那么服务器就会重传FIN报文,客户端在处于TIME_WAIT期间就是在等待服务器发起的重传,如果超出等待时间还没等到重传的报文就会默认ACK正常送达,此时TIME_WAIT就可以释放了。

CLOSE_WAIT是被动发起的一方的状态

TIME—WAIT是主动发起的一方的状态


http://www.ppmy.cn/ops/100621.html

相关文章

智能新时代:探索【人工智能】、【机器学习】与【深度学习】的前沿技术与应用

目录 1. 引言 1.1 人工智能的概念与历史 1.2 机器学习与深度学习的演进 1.3 计算机视觉的崛起与应用场景 2. 人工智能基础 2.1 什么是人工智能&#xff1f; 2.2 人工智能的分类 2.3 人工智能的现实应用 3. 机器学习 3.1 机器学习的定义与基本原理 3.2 机器学习的主要…

如何给文档加密?文档加密软件是什么样的?

一、如何给文档加密&#xff1f; 1、利用第三方加密软件&#xff08;1&#xff09;选择合适的加密软件&#xff1a;市面上有许多专门的加密软件&#xff0c;这些软件通常提供更多的加密选项和更强的安全性能。&#xff08;2&#xff09;操作第三方加密软件&#xff1a;安装并打…

推荐一款低成本 小尺寸数字脉冲编码调制(PCM)输入D类功率放大器 MAX98357AETE+T 兼具AB类性能

MAX98357AETET是数字脉冲编码调制(PCM)输入D类功率放大器&#xff0c;可提供AB类音频性能&#xff0c;同时具有D类的效率。器件在I2S/左对齐模式下通过单个增益设置输入可提供5中可选择增益(3dB、6dB、9dB、12dB、15dB)&#xff0c;在TDM模式下为固定12dB增益。 数字音频接口高…

Linux驱动学习之内核poll阻塞

在linux系统编程课程中学习过多路IO复用&#xff0c;简单来说就三个函数select&#xff0c;poll&#xff0c;epoll。 对于select 此函数是跨平台的&#xff0c;可以在windows&#xff0c;Linux中使用。 对于poll与epoll 只能在linux平台下使用&#xff0c; epoll底层实现是一个…

WebSocket、Socket和Netty的关系

目录 WebSocket、Socket和Netty的关系 WebSocket Socket Netty 关系总结 Socket API 有那些&#xff1f; 1. socket() 2. bind() 3. listen() 4. accept() 5. connect() 6. send() 和 recv() 7. close() 8. shutdown() 9. inet_pton() 和 inet_ntop() 10. setso…

Windows系统安装MySQL

下载MySQL 打开网址MySQL :: Download MySQL Community Server点击图下所示位置Download 进入图下所示界面&#xff0c;点击图下所示位置不登录下载 已下载完成 安装MySQL 将下载好的压缩包解压到一个专门的位置&#xff0c;该软件为绿色版软件&#xff0c;解压即可使用 配置…

Spring 中的BeanPostProcessor

BeanPostProcessor 是 Spring Framework 中的一个接口&#xff0c;用于对 bean 实例进行自定义处理&#xff0c;它位于 org.springframework.beans.factory.config 包下。该接口允许开发者在 Spring 容器创建 bean 实例后进行处理&#xff0c;或在 bean 实例初始化过程中进行自…

单调栈 LeetCode 1130. 叶值的最小代价生成树

目录 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 给你一个正整数数组 arr&#xff0c;考虑所有满足以下条件的二叉树&#xff1a; 每个节点都有 0 个或是 2 个子节点。数…

论坛系统登录测试结果

目录 1 登录成功1.1 输入合法已注册手机号 2 登录失败2.1 输入未注册手机号2.2 输入非法手机号2.3 输入错误、过期验证码 论坛系统——部分测试用例 1 登录成功 1.1 输入合法已注册手机号 打开登录界面 输入已注册手机号 点击发送验证码 输入验证码&#xff0c;点击登录按钮 …

架构师面试题系列之Spring MVC面试专题及答案(31题)

目录 1、什么是 SpringMvc?说一下你对它的理解2、SpringMVC 的优点 :3、SpringMVC 工作原理?4、SpringMVC 的主要组件?5、讲下 SpringMvc 的执行流程6、SpingMvc 中的控制器的注解一般用那个,有没有别的注解可以替代?7、如果在拦截请求中,想拦截 get 方式提交的方法,怎么…

Python接口自动化测试:断言封装详解

在进行API接口测试时&#xff0c;断言起着至关重要的作用。断言是用于验证预期结果与实际结果是否一致的过程。在Python中&#xff0c;我们可以利用一些库来实现断言功能。 1. 安装必要的库 在Python中&#xff0c;我们主要会使用两个库&#xff1a;requests和jsonpath。requ…

解析阿里巴巴中国站商品详情API返回值的更新与变化

阿里巴巴中国站&#xff08;通常指的是1688.com&#xff0c;阿里巴巴的国内批发平台&#xff09;的商品详情API返回值可能会随着平台功能的更新、数据结构的调整或API版本的迭代而发生变化。为了准确解析这些更新与变化&#xff0c;你可以采取以下几个步骤&#xff1a; 1. 查阅…

2024焊工操作证考试在线模拟考试题

焊工证考试试题分为理论《焊工理论知识》考试和《焊工实操知识》专业能力考核。 焊工证考试试题理论知识考试采用闭卷电脑答题方式&#xff1b;理论知识考试和实操考核均实行百分制&#xff0c;焊工证考试成绩皆达80分及以上者为合格。 以下为焊工理论考试模拟试题&#xff0c…

apache httpclient速成

目录标题 快速使用连接池参数连接池状态清除闲置连接evictIdleConnections删除过期连接 timeToLive 和evictExpiredConnections 注意释放内存关闭流 http和netty的关系 导入依赖 <dependency><groupId>org.apache.httpcomponents.client5</groupId><artif…

QT通过信号传递参数至槽函数(不通层级通信)

传递参数参数多个&#xff0c;采用map&#xff0c;一直insert 前提&#xff0c; //map类型 typedef QMap <unsigned int , QByteArray> Map;//信号和槽的声明 signals:void sigToCems(InfoMap);void slotFromEms(Map Map);// 发射点&#xff1a;由事件触发 //Addr_EM…

龙旭 付玲云新歌推出原创歌曲热榜

盘点2024年8月全国受关注的经典热门歌曲你更爱那首&#xff1f; 歌曲1.《甜妹专属BGMentertainer》&#xff0c;2.情歌专属《尘世情缘》情歌唱给谁来听&#xff0c;3.巜迟来的情话》听完敢不敢留下你最想对TA说的话如果在18我没能送你花&#xff0c;那到28我请你喝酒吧&#x…

Linux驱动开发—设备模型框架 kobject创建属性文件

文章目录 什么是属性文件&#xff1f;1. sysfs 与 kobject2. 属性文件的作用3. 属性文件的基本操作4. 典型的属性文件用例5. 创建属性文件的步骤6.示例代码7.效果图 使用 ATTR 宏定义优化__ATTR用法解析1. __ATTR() 宏的定义2. __ATTR() 宏的参数3.优化示例 优化关键点解析1. 数…

Java与C#在中国:我们在信息技术领域的脆弱性和依赖性

2019年8月&#xff0c;微软公司宣布停止在俄罗斯销售新产品和服务&#xff0c;并暂停相关更新和授权。这一决定对俄罗斯用户和企业造成了不小的冲击。 2024年6月&#xff0c;微软陆续关闭中国线下门店授权。微软官方给出的回应是&#xff1a;为了满足客户不断变化的需求&#…

linux命令使用

vi可打开&#xff0c;可创建&#xff0c;cat只能打开已有的文件 rm -r 删除文件夹-r&#xff1a;这个选项代表“递归”&#xff08;recursive&#xff09;。当你用 -r 选项与 rm 一起使用时&#xff0c;rm 会递归地删除目录及其内容&#xff0c;包括所有子目录和文件。 pip i…

并行程序设计基础——MPI不连续数据发送(1)

目录 一、派生数据类型 二、定义新数据类型 1、连续复制的类型生成 2、向量数据类型的生成 3、索引数据类型的生成 4、结构数据类型的生成 5、新类型递交和释放 前面各节介绍的MPI程序设计都是发送或接收连续的数据,其实MPI还可以处理不连续的数据,基本方法有…