码迷,mamicode.com
首页 > 其他好文 > 详细

TCP三次握手与四次挥手

时间:2020-02-28 01:30:55      阅读:58      评论:0      收藏:0      [点我收藏+]

标签:一起   tab   nal   建立连接   序列   服务端   传输协议   网络协议   code   

一、网络模型

网络模型一般是指OSI七层参考模型TCP/IP四层参考模型。这两个模型在网络中应用最为广泛。

技术图片

提问:各层的网络协议有哪些?(以下只是部分)

  • 应用层:HTTP、SMTP、SSH
  • 传输层:TCP、UDP 
  • 网络层:IP、路由表
  • 网络接口层:以太网

二、TCP连接

1、TCP连接的特点:

  • 面向连接的、可靠的传输协议
  • TCP连接不是物理连接(不是电线的两端连接),只有建立TCP连接之后,客户端和服务端才可以开辟资源,比如建立Socket连接。
  • 用户进程与服务器进程完成一次通信都需要完成三个阶段:建立连接、传输数据、断开连接。
  • TCP建立连接需要三次握手,断开连接需要四次挥手。

2、TCP连接过程

(本文暂时跳过了序列号seq和确认号ack的讲解,只讲以下3个标志位)

(1)标志位

  • SYN(Synchronize):发起建立连接的标志。
  • ACK(Acknowledge):确认/应答的标志。
  • FIN(Finally):发起断开连接的标志。

(2)TCP连接的两端

  • 客户端:主动打开/关闭连接的一方。
  • 服务端:被动打开/关闭连接的一方。

(3)三次握手过程:

  • 第一次握手:客户端首先发送一个带有SYN的报文给服务端,表示请求建立连接,并进入SYN-SENT(同步已发送)状态,等待服务端确认。
  • 第二次握手:服务端发送一个带有SYN+ACK的报文给客户端,表示收到并确认客户端发送的连接请求报文,同时服务端也请求和客户端建立连接,此时服务端进入SYN-RCVD(同步收到)状态。
  • 第三次握手:客户端会再一次发送一个带有ACK的报文给服务端,表示客户端也确认收到服务端的应答和连接请求报文。当服务端收到报文后,客户端和服务端进入ESTAB-LISHED(已建立连接)状态,至此完成三次握手,双方正式建立了连接通信,可以进行数据传输。

技术图片

提问:为什么TCP建立连接是三次握手而不能是两次握手?

通信是双向的,目的是为了双方彼此建立可靠的连接。如果仅仅是两次握手,仅客户端能够确认服务端的应答,而服务端无法确认客户端是否收到服务端的连接请求,所以客户端仍需再一次发送ACK报文给服务端表示应答,服务端收到后双方才算正式建立连接通信。

(4)四次挥手过程:

  • 第一次挥手:客户端首先发送一个带有FIN的报文给服务端,表示请求断开连接,即客户端已经没有数据要发送了,此时客户端进入FIN-WAIT-1(终止等待1)状态。
  • 第二次挥手:服务端发送一个带有ACK的报文给客户端,表示确认收到客户端的断开连接请求报文,此时服务端进入CLOSE-WAIT(关闭等待)状态。客户端收到服务端的应答后,客户端就进入FIN-WAIT-2(终止等待2)状态。这个时候如果服务端继续发送数据,客户端依然要接受。
  • 第三次挥手:服务端再最后的数据发送完毕后,会再次发送一个带有FIN+ACK的报文给客户端,表示服务端此时同意断开连接,并向客户端请求断开连接,此时服务端进入LAST-ACK(最后确认)状态。
  • 第四次挥手:客户端再次收到服务端的应答和断开连接请求报文后,会再一次发送一个带有ACK的报文给服务端,表示客户端也确认收到服务端的断开连接请求,此时客户端就进入了TIME-WAIT(时间等待)状态,当服务端收到客户端的应答报文后,就立刻进入CLOSED(关闭连接)状态,而客户端必须经过2MSL(最长报文段寿命)的时间、并且这个期间没有再次收到FIN报文,才进入CLOSED状态。可以看到,服务端结束TCP连接的时间要比客户端早一些。

技术图片

提问:为什么TCP断开连接需要四次挥手?

因为TCP连接是可靠的连接。当服务端收到FIN报文后,很可能不会立即关闭Socket,因为此时服务端的数据传输可能还没发送完毕,所以此时只能先回一个ACK报文,告诉客户端:“你发的FIN报文我收到了,只有等我所有数据都发送完毕,我才能发送FIN报文给你”。因此不能在第二次挥手的时候就一起发送ACK+FIN报文,故需要四次挥手。

提问:为什么客户端TIME_WAIT状态需要等待2MSL(最大报文段生存时间)才能进入CLOSE状态? 

假设网络是不可靠的,有可能客户端最后发送的ACK报文丢失,此时服务端没有收到客户端的应答,会不断发送FIN报文给客户端,所以TIME-WAIT状态就是客户端用来重发可能丢失的ACK报文,它必须确认服务端收到了ACK报文。客户端会设置一个计时器,等待2MSL的时间,如果在该时间内再次收到FIN报文,客户端会重发ACK数据并再次等待2MSL,直到这2MSL时间内都没收到服务端的FIN报文,客户端才推断ACK报文被服务端成功接收,此时才结束客户端的TCP连接。

(所谓的2MSL是指两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最长时间)

补充:知乎上有个形象的示例,再次说明TCP连接为什么是三次握手,而不是两次或四次?

技术图片

TCP三次握手与四次挥手

标签:一起   tab   nal   建立连接   序列   服务端   传输协议   网络协议   code   

原文地址:https://www.cnblogs.com/ZekiChen/p/12370752.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!