首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

一文让你更清晰掌握TCP协议的“三次握手”与“四次挥手”

大家好,今天墨风小编为大家分享下关于TCP协议中关于“三次握手”、“四次挥手”的技术知识,让你更清晰地掌握理解,易学易懂。好了,直接开讲:

一、TCP相关概念知识

TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

TCP 用于应用程序之间的通信,当应用程序希望通过 TCP 与另一个应用程序通信时,它会发送一个通信请求。这个请求必须被送到一个确切的地址。在双方“握手”之后,TCP 将在两个应用程序之间建立一个全双工 (full-duplex) 的通信。这个全双工的通信将占用两个计算机之间的通信线路,直到它被一方或双方关闭为止。

TCP在传输之前会进行三次沟通,一般称为“三次握手”,传完数据断开的时候要进行四次沟通,一般称为“四次挥手”。

TCP中的两个序号和三个标志位

(1)序号:seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。

(2)确认序号:ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,ack=seq+1。

(3)标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义如下:

URG:紧急指针(urgent pointer)有效。

ACK:确认序号有效。

PSH:接收方应该尽快将这个报文交给应用层。

RST:重置连接。

SYN:发起一个新连接。

FIN:释放一个连接。

二、TCP连接的“三次握手”

1、所谓的“三次握手”

即对每次发送的数据量是怎样跟踪进行协商使数据段的发送和接收同步,根据所接收到的数据量而确定的数据确认数及数据发送、接收完毕后何时撤消联系,并建立虚连接。为了提供可靠的传送,TCP在发送新的数据之前,以特定的顺序将数据包的序号,并需要这些包传送给目标机之后的确认消息。

2、“三次握手”过程

在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接:

第一次握手:客户机的 TCP 首先向服务器的 TCP 发送一个连接请求报文段。这个特殊的报文段中不含应用层数据,其首部 SYN 标志置为1。另外,客户机会随机选择一个起始序号seq=x(连接请求报文不携带数据,但要消耗掉一个序号)

第二次握手:服务器的 TCP 收到连接请求报文段后,如同意连接,就会向客户机发回确认,并为该 TCP 连接分配 TCP 缓存和变量。在确认报文段中,SYN 和 ACK 都置为1,确认号字段为ack = x+1,并且服务器随机产生起始序号seq = y。确认报文段同样不包含应用层数据。

第三次握手:当客户机收到确认报文段后,还要向服务器给出确认,并且也要给该连接分配缓存和变量。这个报文段 ACK 标志位置为1, 序号字段seq = x+1,确认号字段ack=y+1。

如下图(1)所示:

SYN:同步位;seq :起始序号;ack:确认号字段

1)SYN = 1, seq = x

2)SYN = 1, ACK = 1, seq = y, ack = x+1

3)ACK = 1, seq = x+1,ack = y+1

图(1) TCP三次握手过程示意图

3、为什么需要三次握手?

如果发送两次就可以建立连接话,那么只要客户端发送一个连接请求,服务端接收到并发送了确认,就会建立一个连接。但如果一个连接请求在网络中跑的慢,超时了,这时客户端会从发请求,但是这个跑的慢的请求最后还是跑到了,然后服务端就接收了两个连接请求,然后全部回应就会创建两个连接,浪费资源!如果加了第三次客户端确认,客户端在接受到一个服务端连接确认请求后,后面再接收到的连接确认请求就可以抛弃不管了。

4、“三次握手”举例说明

A:“喂,你好,我是A,你听得到吗?” A->SYN_SEND

B:“我听得到,我是B,你听得到我吗?” 应答与请求同时发出 B->SYN_RCVD | A->ESTABLISHED

A:“可以,我能听到你,今天balabala……” B->ESTABLISHED

建立链接,开始通话.....

三、TCP连接的“四次挥手”

1、所谓的“四次挥手”

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

2、“四次挥手”过程

在TCP/IP协议中,若需中断传输,采用四次挥手断开一个连接:

第一步:客户机打算关闭连接,就向其 TCP 发送一个连接释放的报文段,并停止发送数据,主动关闭 TCP 连接,该报文段的 FIN 标志位置为1, seq = u,它等于前面已传送过的数据的最后一个字节序号加1.

第二步:服务器收到释放连接的报文段后即发出确认,确认号为ack = u+1,而这个报文段自己的序号seq=v,等于它前面传送过的数据最后一个字节的序号加1。此时,客户机到服务器这个方向的连接就释放了,TCP 连接处于半关闭状态,但服务器发送数据,客户机仍然要接受,即从服务器到客户机这个方向的连接并未关闭。

第三步:若服务器已经没有要向客户机发送的数据,就通知 TCP 释放连接,此时其发出 FIN = 1的连接释放报文段。

第四步:客户机收到连接释放的报文段后,必须发出确认。在确认报文段中,ACK=1,确认号ack=w+1,序号seq=u+1,此时TCP连接还没有释放掉,必须经过实践等待计时器设置时间 2MSL(最长报文段寿命 Maximum Segment Lifetime) 后,进入连接关闭状态。

如下图(2)所示:

FIN:终止位;seq :起始序号;ack:确认号字段

1)FIN = 1, seq = u

2)ACK = 1, seq = v, ack = u+1

3)FIN = 1, ACK = 1, seq = w,ack = u+1

4)ACK = 1,seq = u+1, ack = w+1

图(2) TCP四次挥手过程示意图

扩展:什么是2MSL?MSL即Maximum Segment Lifetime,也就是报文最大生存时间,它(MSL)是任何报文段被丢弃前在网络内的最长时间。那么,2MSL也就是这个时间的2倍。其实我觉得没必要把这个MSL的确切含义搞明白,你所需要明白的是,当TCP连接完成四个报文段的交换时,主动关闭的一方将继续等待一定时间。

3、为什么TCP协议终止链接要四次?

当主机A确认发送完数据且知道B已经接受完了,想要关闭发送数据口(当然确认信号还是可以发),就会发FIN给主机B。主机B收到A发送的FIN,表示收到了,就会发送ACK回复。

但这时B可能还在发送数据,没有想要关闭数据口的意思,所以FIN与ACK不是同时发送的,而是等到B数据发送完了,才会发送FIN给主机A。A收到B发来的FIN,知道B的数据也发送完了,回复ACK, A等待2MSL以后,没有收到B传来的任何消息,知道B已经收到自己的ACK了,A就关闭链接,B也关闭链接了。

总结一下就是:TCP是双向的,所以需要在两个方向分别关闭,每个方向的关闭又需要请求和确认,所以一共就4次。

4、“四次挥手”举例说明

A:“喂,我不说了。”A->FIN_WAIT1

B:“我知道了。等下,上一句还没说完。Balabala…..”B->CLOSE_WAIT | A->FIN_WAIT2

B:“好了,说完了,我也不说了。”B->LAST_ACK

A:“我知道了。”A->TIME_WAIT | B->CLOSED

A等待2MSL,保证B收到了消息,否则重说一次”我知道了”,A->CLOSED

备注说明

之前查阅过好多资料,网上大部分示意图不太准确,描述也略有出入。本文为墨风小编在平时工作中,根据自己的理解,参考部分资料,亲自编辑并绘图,若文档有不太清晰的地方,欢迎大家指出,可私信小编哦。

编辑:焦玉涛

图文:焦玉涛

版权:焦玉涛

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190110G14OB100?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券