三次握手和四次挥手_TCP的三次握手、四次挥手

前面介绍了TCP协议是OSI参考模型中传输层的代表协议,因此TCP协议是为了保障通信可靠性的,那具体TCP协议是如何保障通信可靠性的呢?那就是TCP协议通过“三次握手”的建立连接的方式和“四次挥手的”断开连接的方式保障的。

1、三次握手

物理层、数据链路层在物理层面上架设好了通信链路,网络层确定了通信双方的地址,那下一步就是传输层建立逻辑层面上的通信连接,将从应用层获得的报文数据从源端发送给接受端。TCP的三次握手就是在发送数据前通过“三次握手”的方式建立起这个通信连接,建立这个连接的目的是让源端和目的端确认一下双方的发送报文能力和接收报文能力是正常的,实际上就是通过三次握手这个操作将下面的表填完整:

3b5ba0cf8426a0e0ca86c10bdcbf6513.png
图1.1 三次握手要填充的表格

下面具体介绍三次握手的过程,并在每次握手时填充这个表格,当表格填满后,意味着源端和目的端已确认完毕双方的发送报文能力和接收报文能力是正常的,三次握手结束,通信双方的连接已成功建立。

1.1 TCP报文首部

在介绍三次握手前先介绍一下TCP报文的首部,报文首部可以理解为报文的元数据,里面存放着与这次报文相关的其他信息,图我就不摆了,介绍一下跟三次握手相关的报文首部字段。

(1)序号seq

对字节流的编号。例如第一个字节的序号为 301,如果携带的数据长度为 100 字节,那么下一个报文段的序号应为 401。注意第一份报文段的序号是随机生成的,后面的报文段序号是根据上一个报文段序号及报文长度生成的。

(2)确认号ack

期望收到的下一个报文段的序号。例如 B 正确收到 A 发送来的一个报文段,序号为 501,携带的数据长度为 200 字节,因此 B 期望下一个报文段的序号为 701,B 发送给 A 的确认报文段中确认号就为 701。

(3)SYN

控制位的一种,用于建立连接,该位设为 1,表示希望建立连接,并对第一份报文的序号进行随机初始化。

(4)ACK

控制位的一种,确认应答的字段有效,TCP规定除了最初建立连接时的 SYN 包以外该位必须设为 1。

(5)FIN

控制位的一种,当FIN=1,表明此报文的发送方的数据已经发送完毕,要求关闭连接。

1.2 三次握手具体过程

TCP三次握手的过程如图所示,图来自连接3。

b333e73dae44e8e80c532e184d23f8ab.png
图1.2 TCP三次握手过程

(1)第一次握手

Client端将SYN置为1,表示希望与Server端建立连接;序号seq初始化为J,并将该数据包发送给Server端,Client进入SYN_SENT状态,等待Server确认。

(2)第二次握手

Server端检查报文发现SYN为1,知道了Client端想建立连接;Server端将SYN置为1,表示Server端也希望与Clinet端建立连接;Server端将ACK置为1,表示收到了Client端建立连接的请求;Server端将seq初始化为K;Server端将ack置为J+1,这里ack=seq + 1,还有疑问(如果控制位占1字节,为什么第三次握手时有ACK=1、SYN=1,ack为什么不是+2?如果+1只是告诉服务端收到了消息,那ACK控制位就已经达到目的了,为什么还要多次一举再加一个ack?)。第二次握手包括服务端确认客户端发来的报文和服务端向客户端发送报文两个过程。

第二次握手时表格填充结果如下:

376e7c7a5f1deee2e0934cae451cc2b3.png
图1.3 第二次握手表格填充

(3)第三次握手

Client收到报文后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。第三次握手包括客户端确认服务端发来的报文,客户端向服务端发送报文和服务端确认客户端发来的报文三个过程。

第三次握手客户端确认信息后填充表格如下:

d5b943d2f00ac37bdfb54b6fe9949a52.png
图1.4 第三次握手客户端确认信息表格填充

第三次握手服务端确认信息后填充表格如下:

5d5d30438ea387b5b4b31855017c32e5.png
图1.5 第三次握手服务端确认信息表格填充

至此,表格填充完毕,三次握手也结束,连接成功建立。有些面试官会问为什么不是2次握手?因为2次握手表格填充不完,源端和目的端无法确认双方的收发能力;为什么不是4次握手?3次握手表格就填充完毕了,不需要再多一次握手了。

2、四次挥手

三次握手是建立TCP连接,四次挥手是断开TCP连接,即客户端和服务端总共要收发4个包才能确定断开连接。

2.1 四次挥手的具体过程

四次挥手的过程如图所示,图摘自连接4:

e107c8efa1045a65f66709e08ef070c8.png
图2.1 TCP四次挥手过程图

(1)第一次挥手

假设客户端主动发起断开请求,客户端向服务端发送报文,报文首部包括FIN=1,这个控制位代表客户端想要断开连接;序列号seq=u,这时客户端进入FIN-WAIT-1(终止等待1)状态,停止发送数据,并等待服务端的确认。

(2)第二次挥手

服务端收到客户端的报文后发出确认报文,控制位ACK=1;确认号ack=u+1;序列号seq=v;然后服务端就进入CLOSE-WAIT(关闭等待)状态。TCP服务端会告知上层的应用进程来自客户端的连接即将关闭,让应用程序做好相应的准备。此时客户端已经没有数据向服务端发送了,但服务端向客户端发送数据,客户端依然能接收。

(3)第三次挥手

客户端收到服务器确认报文后,进入FIN-WAIT-2状态。此时服务器再次发送报文,报文首部控制位FIN=1,表示服务端向客户端发送断开连接请求;确认标志ACK=1;确认序号ack=u+1;序号seq=w,然后服务器进入LAST-ACK(最后确认态),等待客户端确认。

(4)第四次挥手

客户端收到了服务端的断开连接的报文后,必须发出确认报文,标志位ACK=1;确认号ack=w+1;序号seq=u+1;之后客户端就进入了TIME-WAIT(时间等待)状态。注意此时客户端的TCP连接还没有释放,必须经过2*MSL(最长报文段寿命)的时间后,客户端才进入CLOSED状态关闭连接。而服务端只要收到了客户端发送的确认报文后就会进入CLOSED状态关闭服务端连接。当客户端和服务端都进入了CLOSED状态后,客户端和服务端之间的连接才完全断开。

2.2 为什么会有TIME_WAIT状态?

上面介绍第四次挥手的过程中,客户端在发送完给服务端的回执报文后没有立刻进入CLOSED状态,而是进入TIME-WAIT状态,然后等待2*MSL(最长报文段寿命)的时间后才进入CLOSED状态,这是为什么?原因有以下两点:

  • 客户端发送给服务端回执后,有可能这个回执报文在传输途中丢失等原因,服务端并没有收到,此时服务端会再次向客户端发送FIN=1的断开请求报文,如果客户端没有等待2*MSL时间而直接进入了CLOSED状态,客户端就会收不到服务端再次发送的断开连接的请求报文,导致服务端无法进入CLOSED状态;
  • 等待一段时间是为了让本连接持续时间内所产生的所有报文都从网络中消失,使得下一个新的连接不会出现旧的连接请求报文。

注:MSL是Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。

2.3 为什么是四次挥手而不是三次或者五次?

第二次挥手和第三次挥手都是服务端向客户端发送报文,第二次挥手是服务端收到了客户端的断开请求,通知客户端俺收到了,此时客户端没有数据向服务端发送了,但不代表服务端也没有数据向客户端发送,因为服务端要把剩余还没有发送的报文发送完毕再断开连接;第三次挥手是服务端数据全部发送完毕,向客户端发送断开请求报文(FIN=1)。

如果是三次挥手,即把服务端向客户端发送报文的第二次挥手和第三次挥手合为一次,会造成服务端发送了回执后立刻又发送断开请求,造成服务端有数据没有全部发送至客户端,因此必须将第二次挥手和第三次挥手分开;五次挥手则完全没必要,多此一举。

参考

herongwei:一文搞定 UDP 和 TCP 高频面试题!​zhuanlan.zhihu.com
b61eab7581b7926fedcc83a11fca85e1.png
为什么三次握手的时候ack=seq+1_网络_oldfish_C的博客-CSDN博客​blog.csdn.net
178711aff7fc480c54c25561dde2b05e.png
简述TCP的三次握手过程 - 清风木 - 博客园​www.cnblogs.com
0cd07514c585fa3760a0182adc2232d1.png
TCP三次握手和四次挥手通俗理解 - jainss - 博客园​www.cnblogs.com
64b864938442daa378932a12d73bdc63.png
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值