了解TCP传输控制协议

了解TCP传输控制协议

在这里插入图片描述
在这里插入图片描述

TCP的定义

TCP即传输控制协议,全称为Transition Control Protocol,工作在传输层上主要职责是负责主机之间进程到进程的通信,其次可以保证可靠性,不能保证安全性。

  1. TCP会尽自己所能,尽量将数据发送给对方;但并不能保证100%可以发送给对方
  2. TCP会在数据发送不到对方的情况下,会给应用层一个错误提示,告知用户发送失败
  3. TCP可以保证接收方(应用层)严格按照发送时的数据顺序接收
  4. TCP保证数据不会出现无意间的损坏(UDP 也做到这点)
  5. TCP尽可能地维护网络质量

TCP的特性

1、确认应答机制(ACK):

确认应答机制是可靠传输的最核心机制:接收方反馈一个应答报文(ACK),表示已经收到
在这里插入图片描述

但是可能出现一种情况,后发先至,即接收到的数据是乱序的。

在这里插入图片描述

如果存在对应关系,即使出现了这种情况,也可以顺利的确立应答。
在这里插入图片描述

虽然能够正确的建立应答,但是额外的信息太多,占用了很多带宽,可以进行编号,应答的时候针对编号进行应答,这样既能保证没有歧义,也能不浪费带宽。

在这里插入图片描述

(1) 图1:正确顺序传达正确意思

在这里插入图片描述

(2) 图2:错误顺序传达正确意思

序号和确认序号并不是按照一条两条来编的,而是按照字节来编的,每一个字节均有一个编号。此时的ACK本质上是一个字段为1的报文,既是确认序号,也是下次发送的序号。

在这里插入图片描述

为了防止网络攻击,初始的序号是随机的,例如上图,初始序号为66,发送了22字节,应该到87,则回复88,认为88之前的都已经收到了。

在这里插入图片描述

2、超时重传

确认应答是比较理想的情况,但是数据再传输过程中,可能是丢包的。上图为例,如果A给B发信息,并未收到回复,此时有三种情况。

  1. B不想回
  2. B没有收到——A发出的请求丢失
  3. B收到了,恢复了,A没收到——B应答的ACK丢失

因为丢失的时候,无法确定哪一种情况,因此统一处理,当发送数据之后,TCP内部就会启动一个定时器,达到一定时间没有收到ACK之后,定时器就会触发重传消息的操作——超时重传

如果第二次重传依旧没有成功,就会存在两个超时时间,往往t2 会比 t1 更长

在这里插入图片描述

TCP 抱着一种 “悲观的态度”,当一次丢包重传之后,TCP 就觉得大概率后面的重传也没用,所以就隔一个更长的时间,节省带宽。

上述丢包有两种情况,一种是请求丢失——重传没有问题;一种是 ACK 丢失,重传就意味着接收方收到了相同的数据

在这里插入图片描述

TCP 会在内部进行数据去重 (以序号为 key 进行去重),保证应用层读到的数据不是重复数据。

3、建立连接 三次握手

TCP三次握手的过程——情景模拟

  • 发送方:老铁,可以听得到我说话吗,老铁。
  • 接收方:可以听到,你听得到吗?
  • 发送方:听到了,那我开始说正事了。

这个故事是用来模拟TCP三次握手的,也是在所有通俗解释三次握手的典型例子。

为什么要建立连接?

  1. 为了保证双方能够正常通信,更好的保证可靠性,建立连接的过程其实就是验证双方各自的发送能力和接受能力是否正常。
  2. 协商一些参数、例如序号的初始值。

怎样建立连接?
在这里插入图片描述

第一次握手:刚开始A和B都不知道听筒和话筒是否正常,因此说一句话。

第二次握手:接收方接收到了信息,需要给发送方一个回复。

第三次握手:发送方再给接收方一个回复,说明都正常。

在这里插入图片描述

我理解的:

现在2个人 不知道 对方的听筒可以听到 话筒能不能使用保持疑问?

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

经过以上三次握手,证明网络建立连接时候是正常的

在这里插入图片描述

第一次握手:客户端向服务器发送报文SYN(SEQ=x,SYN=1),并进入SYN_SENT状态,等待服务器确认。SEQ是序列号
第二次握手包含两部分,一部分是请求,另一部分是应答,应答是ACK=x+1,发送SYN SEQ=y,此时服务器进入SYN_RECV状态
第三次握手,客户端收到了ACK,并对SYN进行应答,完成之后进入Establishment状态,完成三次握手。
在这里插入图片描述

建立连接的过程,相当于通信双方各自给对方发送 SYN,在各自给对方发送给 ACK,只不过中间的 ACK 和 SYN 合二为一了,于是最后就是"三次握手。

几个重要的状态:

  • LISTEN: 正在侦听来自远方的 TCP 端口的连接请求,服务端启动后处于 LISTEN 状态用于监听不同客户端的 TCP 请求并建立连接
  • SYN_SEND / SYN_RCVD: 建立连接的中间过程,若连接顺利的话(建立连接过程也可能丢包),这两个状态就一瞬消失
  • ESTABLISHEN: 连接建立完毕 (验证了通信双方的发送和接受能力都正常),可以进行数据传输。

为什么不能两次握手:

两次握手只能保证单向连接是通畅的 (为了实现可靠数据传输, TCP 协议的通信双方,都必须维护一个序列号,以标识发送出去的数据包中,哪些是已经被对方收到的;三次握手的过程即是通信双方相互告知序列号起始值,并确认对方已经收到了序列号起始值的必经步骤;如果只是两次握手,至多只有连接发起方的起始序列号能被确认,另一方选择的序列号则得不到确认)
在这里插入图片描述

4、四次挥手 双方各自向对方发起建立连接的请求,再各自给对方回应,只不过,中间的 FIN 和 ACK 不一定能合并在一起

在这里插入图片描述

  • 第一次挥手: 客户端向服务器端发送断开 TCP 连接请求的 [FIN,ACK] 报文,在报文中随机生成一个序列号 SEQ=u,表示要断开 TCP 连接,此时,客户端进入FIN_WAIT_1 (终止等待1) 状态
  • 第二次挥手:当服务器端收到客户端发来的断开 TCP 连接的请求后,回复发送 ACK 报文,表示已经收到断开请求。回复时,随机生成一个序列号 SEQ=v;由于回复的是客户端发来的请求,所以在客户端请求序列号 SEQ=u 的基础上加 1,得到 ack=u+1此时,服务端就进入了CLOSE_WAIT (关闭等待) 状态客户端收到ACK后,就进入FIN_WAIT_2 (终止等待2) 状态
  • 第三次挥手:服务器端在回复完客户端的 TCP 断开请求后,不会马上进行 TCP 连接的断开。服务器端会先确认断开前,所有传输到客户端的数据是否已经传输完毕**。确认数据传输完毕后才进行断开,向客户端发送 [FIN,ACK] 报文,设置字段值为 1**。再次随机生成一个序列号 SEQ=w;由于还是对客户端发来的 TCP 断开请求序列号 SEQ=u 进行回复,因此 ack 依然为 u+1,此时,服务器就进入了LAST_ACK (最后确认) 状态
  • 第四次挥手:**客户端收到服务器发来的 TCP 断开连接数据包后将进行回复,表示收到断开 TCP 连接数据包。**向服务器发送 ACK 报文,生成一个序列号 SEQ=u+1;由于回复的是服务器,所以 ACK 字段的值在服务器发来断开 TCP 连接请求序列号 SEQ=w 的基础上加 1,得到 ack=w+1,此时,客户端就进入了TIME_WAIT (时间等待) 状态;注意此时TCP连接还没有释放,必须经过2MSL (最长报文段寿命) 的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态

在这里插入图片描述


另一篇博客的说法

在断开连接之前客户端和服务器都处于ESTABLISHED状态,双方都可以主动断开连接,以客户端主动断开连接为优。

第一次挥手:客户端打算断开连接,向服务器发送FIN报文(FIN标记位被设置为1,1表示为FIN,0表示不是),FIN报文中会指定一个序列号,之后客户端进入FIN_WAIT_1状态

也就是客户端发出连接释放报文段(FIN报文),指定序列号seq = u,主动关闭TCP连接,等待服务器的确认。

第二次挥手:服务器收到连接释放报文段(FIN报文)后,就向客户端发送ACK应答报文,以客户端的FIN报文的序列号 seq+1 作为ACK应答报文段的确认序列号ack = seq+1 = u + 1

接着服务器进入CLOSE_WAIT(等待关闭)状态,此时的TCP处于半关闭状态(下面会说什么是半关闭状态),客户端到服务器的连接释放。客户端收到来自服务器的ACK应答报文段后,进入FIN_WAIT_2状态。

第三次握手:服务器也打算断开连接,向客户端发送连接释放(FIN)报文段,之后服务器进入LASK_ACK(最后确认)状态,等待客户端的确认。

服务器的连接释放(FIN)报文段的FIN=1,ACK=1,序列号seq=m,确认序列号ack=u+1。

第四次握手:客户端收到来自服务器的连接释放(FIN)报文段后,会向服务器发送一个ACK应答报文段,以连接释放(FIN)报文段的确认序号 ack 作为ACK应答报文段的序列号 seq,以连接释放(FIN)报文段的序列号 seq+1作为确认序号ack。

之后客户端进入TIME_WAIT(时间等待)状态,服务器收到ACK应答报文段后,服务器就进入CLOSE(关闭)状态,到此服务器的连接已经完成关闭。

客户端处于TIME_WAIT状态时,此时的TCP还未释放掉,需要等待2MSL后,客户端才进入CLOSE状态


由客户端到服务器需要一个FIN和ACK,再由服务器到客户端需要一个FIN和ACK,因此通常被称为四次握手。

客户端和服务器都可以主动关闭连接,只有率先请求关闭的一方才会进入TIME_WAIT(时间等待状态)。

为什么挥手需要四次?

这是由于TCP的半关闭(half-close)造成的。半关闭是指:TCP提供了连接的一方在结束它的发送后还能接受来自另一端数据的能力。通俗来说,就是不能发送数据,但是还可以接受数据。

TCP不允许连接处于半打开状态时,就单向传输数据,因此完成三次握手后才可以传输数据(第三握手可以携带数据)。

当连接处于半关闭状态时,TCP是允许单向传输数据的**,也就是说服务器此时仍然可以向客户端发送数据,等服务器不再发送数据时,才会发送FIN报文段,同意现在关闭连接。**

这一特性是由于TCP双向通道互相独立所导致的,也使得关闭连接必须经过四次握手。

可能有些人会有疑惑:为什么中间的ACK和FIN不可以像三次握手那样合为一个报文段呢?

在socket网络编程中,执行close()方法会触发内核发送FIN报文。什么时候调用close()方法,这是由用户态决定的,假如服务器仍有大量数据等待处理,那么服务器会等数据处理完后,才调用close()方法,这个时间可能会很久,而ACK报文则是由系统内核来完成的,这个过程会很快。所以中间的ACK和FIN不能合为一个包。

为什么TIME_WAIT等待的时间是2MSL?

MSL(Maximum Segment LifeTime)是报文最大生成时间,它是任何报文在网络上存在的最长时间,超过这个时间的报文将被丢弃。

因为TCP协议是基于IP协议(位于IP协议的上一层),IP数据报中有限制其生存时间的TTL字段,是IP数据报可以经过的最大路由器的个数,每经过处理它的路由,TTL就会减一。TTL为 0 时还没有到达目的地的数据报将会被丢弃,同时发送 ICMP 报文通知源主机。

MSL的单位为时间,TTL的单位为跳转数。所以MSL应该大于等于TTL变为0的时间,以确保报文已被丢弃。

TIME_WAIT等待的2MSL时间,可以理解为数据报一来一回所需要的最大时间。

2MSL时间是从客户端接收到FIN后发送ACK开始计时的。如果在这个时间段内,服务器没有收到ACK应答报文段,会重发FIN报文段,如果客户端收到了FIN报文段,那么2MSL的时间将会被重置。如果在2MSL时间段内,没有收到任何数据报,客户端则会进入CLOSE状态。

等待2MSL的意义
  1. 保证客户端最后发送的ACK能够到达服务器,帮助其正常关闭。

由于这个ACK报文段可能会丢失,使得处于LAST_ACK状态的服务器得不到对已发送FIN报文段的确认,从而会触发超时重传。服务器会重发FIN报文段,客户端能保证在2MSL时间内收到来自服务器的重传FIN报文段,从而客户端重新发送ACK应答报文段,并重置2MSL计数。
假如客户端不等待2MSL就之间进入CLOSE状态,那么服务器会一直处于LAST_ACK状态。
当客户端发起建立SYN报文段请求建立新的连接时,服务端会发送RST报文段给客户端,连接建立的过程就会被终止。

  1. 防止已失效的连接请求报文段出现在本连接中。

TIME_WAIT等待的2MSL时间,确保本连接内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文段。

TIME_WAIT状态过多有什么危害?

只有主动发起断开请求的一方才会进入TIME_WAIT状态!

  1. 占用系统资源
  2. socket的TIME_WAIT状态结束之前,该socket占用的端口号将一直无法释放。如果服务器TIME_WAIT状态过多,占满了所有端口资源,则会导致无法创建新的连接。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

K8S部署Java项目(Gitlab CI/CD自动化部署终极版)

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…

Android 水波纹扩散效果实现

人生只是一种体验,不必用来演绎完美。 效果图 View源码 package com.android.circlescalebar.view;import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.…

当Vue项目启动后,通过IP地址方式在相同网络段的其他电脑上无法访问前端页面?

当Vue项目启动后,通过IP地址方式在相同网络段的其他电脑上无法访问前端页面,可能是由以下几个原因造成的: 服务监听地址:默认情况下,许多开发服务器(如Vue CLI的vue-cli-service serve)只监听lo…

数字孪生的技术开发平台

数字孪生的开发平台可以基于各种软件和硬件工具来实现,这些平台提供了丰富的功能和工具,帮助开发人员构建、部署和管理数字孪生系统,根据具体的需求和技术要求,开发人员可以选择合适的平台进行开发工作。以下列举了一些常见的数字…

Transformer视频理解学习的笔记

今天复习了Transformer,ViT, 学了SwinTransformer, 还有观看了B站视频理解沐神系列串讲视频上(24.2.26未看完,明天接着看) 这里面更多论文见:https://github.com/mli/paper-reading/ B站视频理解沐神系列串讲视频下(明天接着看&a…

【mysql】 1819 - Your password does not satisfy the current policy requirements

创建mysql账户密码时候提示: 1819 - Your password does not satisfy the current policy requirements 1819-您的密码不符合当前策略要求 下面是执行的sql DROP DATABASE IF EXISTS company;CREATE DATABASE company CHARACTER SET utf8mb4 ;grant all on com…

蓝桥杯备战刷题one(自用)

1.被污染的支票 #include <iostream> #include <vector> #include <map> #include <algorithm> using namespace std; int main() {int n;cin>>n;vector<int>L;map<int,int>mp;bool ok0;int num;for(int i1;i<n;i){cin>>nu…

【服务器数据恢复】ext3文件系统下硬盘坏道掉线的数据恢复案例

服务器数据恢复环境&#xff1a; 一台IBM某型号服务器上有16块FC硬盘组建RAID阵列。上层linux操作系统&#xff0c;ext3文件系统&#xff0c;部署有oracle数据库。 服务器故障&检测&#xff1a; 服务器上跑的业务突然崩溃&#xff0c;管理员发现服务器上有2块磁盘的指示灯…

OSI参考模型和TCP/IP网络参考模型

1、OSI参考模型 1.1 产生背景 为了解决网络之间的兼容性问题,实现网络设备间的相互通讯,国际标准化组织ISO于1984年提出了OSIRM(Open System Interconnection Reference Model,开放系统互连参考模型)。OSI参考模型很快成为计算机网络通信的基础模型。由于种种原因,并没有…

[极客大挑战 2019]LoveSQL1 题目分析与详解

一、题目简介&#xff1a; 二、通关思路&#xff1a; 1、首先查看页面源代码&#xff1a; 我们发现可以使用工具sqlmap来拿到flag&#xff0c;我们先尝试手动注入。 2、 打开靶机&#xff0c;映入眼帘的是登录界面&#xff0c;首先尝试万能密码能否破解。 username: 1 or 11…

Unity Shader - sahder变体剔除

文章目录 吐槽优化方案 - 目前最靠谱的方式shadercsharp 吐槽 我之所以单独写这边文章&#xff0c;是因为之前写的一篇&#xff1a; Unity Shader - Built-in管线下优化变体&#xff0c;编辑后&#xff0c;无法保存&#xff0c;一直提示&#xff1a;操作超时。 等了差不多 3…

StarRocks实战——多维分析场景与落地实践

目录 一、OLAP 系统历史背景 1.1 历史背景与痛点 1.2 组件诉求 二、StarRocks 的特点和优势 2.1 极致的查询性能 2.2 丰富的导入方式 2.3 StarRocks 的优势特点 三、多维分析的运用场景 3.1 实时计算场景 / 家长监控中心 3.2 实时更新模型选择 3.2.1 更新模型UNIQU…

微服务-实用篇

微服务-实用篇 一、微服务治理1.微服务远程调用2.Eureka注册中心Eureka的作用&#xff1a;搭建EurekaServer服务Client服务注册服务发现Ribbon负载均衡策略配置Ribbon配置饥饿加载 3.nacos注册中心使用nacos注册中心服务nacos区域负载均衡nacos环境隔离-namespaceNacos和Eureka…

线程分离属性、线程互斥、死锁、信号量——进程与线程——day11

今天主要学习了线程分离属性、线程互斥、死锁、信号量 线程分离属性&#xff1a;主要是让线程结束后&#xff0c;自动回收线程空间 pthread_attr_initint pthread_attr_init(pthread_attr_t *attr);功能:线程属性初始化pthread_attr_destroyint pthread_attr_destroy(pthread…

k8s(5)

目录 使用Kubeadm安装k8s集群&#xff1a; 初始化操作&#xff1a; 每台主从节点&#xff1a; 升级内核&#xff1a; 所有节点安装docker &#xff1a; 所有节点安装kubeadm&#xff0c;kubelet和kubectl&#xff1a; 修改了 kubeadm-config.yaml&#xff0c;将其传输给…

Redis 16种妙用

1、缓存 2、数据共享分布式 3、分布式锁 4、全局ID 5、计数器 6、限流 7、位统计 8、购物车 9、用户消息时间线timeline 10、消息队列 11、抽奖 12、点赞、签到、打卡 13、商品标签 14、商品筛选 15、用户关注、推荐模型 16、排行榜 1、缓存 String类型 例如&#xff1a;热点…

Magento2常见表的作用

1.sales_sequence_profile 更改订单号或者发票号的前缀及最大值

猫头虎分享已解决Bug || 网络连接问题:NetworkError: Failed to fetch

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

手机打开 第三方 “微信、快手、QQ、电话、信息” 等

前期回顾 Vue3 TS Element-Plus —— 项目系统中封装表格搜索表单 十分钟写五个UI不在是问题_vue3 封装table 配置表格-CSDN博客https://blog.csdn.net/m0_57904695/article/details/135538630?spm1001.2014.3001.5501 目录 &#x1f916; 下载App如下图所示&#xff1a;…

pytorch --反向传播和优化器

1. 反向传播 计算当前张量的梯度 Tensor.backward(gradientNone, retain_graphNone, create_graphFalse, inputsNone)计算当前张量相对于图中叶子节点的梯度。 使用反向传播&#xff0c;每个节点的梯度&#xff0c;根据梯度进行参数优化&#xff0c;最后使得损失最小化 代码…