TCP——三次握手和四次挥手

简介: TCP——三次握手和四次挥手

文章目录

三次握手

四次挥手


三次握手


TCP协议目的是为了保证数据能够在两端准确连续的流动,可以想象两个建立起TCP通道的设备如同接起了一根水管,数据就是水管种的水由一头流向了另一头。然而TCP为了能让一个设备连接多个水管,也就是让一个设备同时与多个设备交互信息,它必须保证不同水管之间不能产生串联或相互影响。


为了确保数据能够正确分发,TCP用一种叫TCB(传输控制块)的数据结构把发给不同设备的数据封装起来,我们可以把该结构看作是信封。一个TCB数据块包含了数据发送双方对应的socket信息以及拥有装载数据的缓冲区。


在两个设备要建立连接发送数据之前,双方都必须做一些准备–分配内存建立起TCB数据块

1.png

1、准备工作

最开始的客户端和服务器都处于CLOSE状态。主动打开连接的是客户端,被动打开的是服务器

TCP服务器进程先创建传输控制块TCB,时刻准备接收客户端进程的请求,此时服务器就进入LISTEN状态


2、一次握手

TCP客户端也是先创建了传输控制块TCB,然后向服务器发出连接请求报文,SYN,报文首部种的同部位(SYN=1),同时选择一个序列号seq=x

此时,TCP进入SYN-SENT(同步已发送状态)。TCP规定,SYN报文段不能携带数据,但需要消耗一个序号

如果是发送,则需要发送一个标志位SYN=1,同时选择一个初始序列号seq=x(随机,客户端或服务器每发送一次+1)


3、二次握手

TCP服务器收到请求报文后,如果同意连接,则发出确认报文。

收到报文,则需要发送一个确认标志位ACK=1,并且确认序列号ack=x+1,然后发出报文,需要一个发送标志位SYN=1,同时选择一个初始序列号seq=y(随机)


4、TCP客户端收到确认后,还要向服务器给出确认。

收到报文,发送一个确认标志位ACK=1,确认序列号ack=y+1,seq=x+1 。

为什么TCP客户端还要最后再发一次确认呢


主要防止已经失效的连接请求报文又突然传送到了服务器,从而产生错误

1.png


四次挥手


数据传输完毕后,双方都可释放连接。最开始的时候,客户端和服务器都是处于established状态。然后客户端主动关闭,服务器被动关闭。

1.png

1、TCP客户端收到一个FIN(关闭连接),用来关闭客户端到服务器的数据传送


2、服务器收到这个FIN,它发回一个ACK

客户端发送完所有的数据,请求关闭连接,向服务器申请关闭,但与此同时,服务器未必就把所有的数据全部向客户端发送完毕,所以在第二步和第三步之间,服务器可以继续数据传输


3、服务器关闭客户端的连接,发送一个FIN给客户端


4、客户端发回ACK报文确认,并将确认序号设置为收到序号+1


为什么客户端最后还要等待2MSL


去向ACK消息最大存活时间(MSL)+ 来向FIN消息的最大存活时间(MSL)


第一,保证客户端发送的最后一个ACK报文能够到达服务器


第二,释放的端口可能重连刚断开的服务器端口,这样依然存活在网络里的老的TCP报文可能与新的TCP连接报文冲突


如果已经建立连接了,但是客户端突然出现故障了怎么办


TCP还设有一个保活计时器。客户端出现故障,服务器不能一直等下去


TCP协议是如何保证可靠传输的


数据包校验:目的是检测数据在传输过程中的任何变化,若校验出包有错,则丢弃报文段并且不给出响应,这时 TCP 发送数据端超时后会重发数据;

对失序数据包重排序:既然 TCP 报文段作为 IP 数据报来传输,而 IP 数据报的到达可能会失序,因此 TCP 报文段的到达也可能会失序。TCP 将对失序数据进行重新排序,然后才交给应用层;

丢弃重复数据:对于重复数据,能够丢弃重复数据;

应答机制:当 TCP 收到发自 TCP 连接另一端的数据,它将发送一个确认。这个确认不是立即发送,通常将推迟几分之一秒;

超时重发:当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段;

流量控制:TCP 连接的每一方都有固定大小的缓冲空间。TCP 的接收端只允许另一端发送接收端缓冲区所能接纳的数据,这可以防止较快主机致使较慢主机的缓冲区溢出,这就是流量控制。TCP 使用的流量控制协议是可变大小的滑动窗口协议。

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
缓存 开发工具 git
【git】解决:remote: Permission to xxxx/xxxx.git denied to xxxx
【git】解决:remote: Permission to xxxx/xxxx.git denied to xxxx
1151 0
|
XML NoSQL Java
Redis - 一篇走心的 RedisUtil 工具类
Redis - 一篇走心的 RedisUtil 工具类
3829 0
Redis - 一篇走心的 RedisUtil 工具类
|
数据处理 C++
C++程序字符串流
C++程序字符串流
136 2
|
缓存 安全 算法
Java面试题:如何通过JVM参数调整GC行为以优化应用性能?如何使用synchronized和volatile关键字解决并发问题?如何使用ConcurrentHashMap实现线程安全的缓存?
Java面试题:如何通过JVM参数调整GC行为以优化应用性能?如何使用synchronized和volatile关键字解决并发问题?如何使用ConcurrentHashMap实现线程安全的缓存?
148 0
|
12月前
|
Java
Properties类的使用
本文介绍了Java中Properties类的使用,它继承自Hashtable,用于处理属性文件。Properties对象可以保存键值对,并且能够从输入流加载或保存到输出流。文章展示了如何读取和写入properties文件,包括使用`setProperty`和`getProperty`方法来设置和获取属性值,以及使用`list`方法打印属性到控制台。同时,还解释了Properties类底层使用的哈希表结构,并提到了字符编码转换问题,特别是在处理中文时会转换成unicode编码。
|
Java Android开发
Android 导航方式切换
Android 导航方式切换
405 1
pnpm无法加载文件 (解决方法 )
pnpm无法加载文件 (解决方法 )
|
存储 算法 搜索推荐
作为程序员必须掌握的经典算法
作为程序员必须掌握的经典算法
|
SQL DataX 文件存储
开源DataX最新版本v202309新增HdfsReader支持parquet文件格式的问题
最近发现,datax更新了最新版本v202309,ds上更新后,同步hive下的parquet文件报错
1144 1
|
大数据 Scala 容器
【建议收藏】|3分钟让你学会Scala Trait 使用
Scala 是一种强大的静态类型编程语言,其中的 Trait 是一种重要的特性。Trait 可以被看作是一种包含方法和字段定义的模板,可以被其他类或 Trait 继承或混入。在本文中,我们将介绍 Scala Trait 的边界(Boundary)的概念,并展示如何使用它来限制 Trait 的使用范围。
341 11