为了能够使浏览器和服务器通信,浏览器和服务器之间通过三次握手,来建立TCP连接。通过四次挥手,来结束TCP连接。
三次握手
过程
- 客户端主动向服务端发起请求(准备开始进行第一次握手)
- 客户端向服务器发起TCP连接请求报文,请求报文中将同步位
SYN
置为1,随机生成一个序列号seq
(第一次握手) - 服务器收到请求后发回一个确认报文,确认报文中同步位
SYN
和确认位ACK
置为1,随机生成一个序列号seq
和返回确认编号ack
(第二次握手) - 客户端收到服务器的确认报文后,返回给服务器一个确认报文,将确认位
ACK
置为1,seq
为第一次握手随机生成的x+1
,ack
为服务器确认报文的序列号+1y+1
(第三次握手) - 双方开始通信
大白话
客户端想要发送数据,告诉服务器他想要建立TCP连接(第一次握手),服务器收到请求后,和客户端说你可以发送数据(第二次握手),客户端得到服务器的确认后和服务器说那我要开始发送数据了(第三次握手),然后双方愉快的开始通信
为什么需要三次握手
第一种说法
确保服务器和客户端都知道对方的序列号还让他们双方都互相知道对方知道,第一次握手是服务器知道客户端的序列号,第二次握手是客户端知道服务器的序列号并且让客户端知道,服务器知道客户端的序列号;第三次握手是让服务器知道,客户端知道服务器的序列号。(双方套娃)
第二种说法
防止已失效的连接请求报文突然又传送到服务器端(谢希仁计算机网络)
如果客户端第一次发送请求连接报文,这个报文因为某种情况发生了滞留,客户端又重新发送请求连接报文到服务器端,双方建立连接,传输完数据后断开了连接。如果这时,滞留的第一次连接请求报文到达了服务端,服务器会误认为客户端又重新发起连接请求,返回确认报文,可是客户端不知道自己发送了连接请求,就不会理睬客户端的确认,造成服务器端白白等着,造成资源浪费。
四次挥手
双方其实都可以释放TCP连接,以客户端为例
过程
- 客户端向服务器端发送释放报文段,并停止发送数据。在报文段首部,将终止控制位
FIN
置为1,随机生成序列号seq
为u(第一次挥手) - 服务器端收到客户端的释放报文段后立即发出确认,确认号
ack
为u+1,随机生成序列号seq
为v,确认字段ACK
为1(第二次挥手) - 当服务器端不需要发送数据时,向客户端发送释放报文段,将终止控制位
FIN
置为1,随机生成序列号seq
为w(第三次挥手) - 客户端收到请求后立即返回确认,并等待
2MSL
时间后才进入close状态(第四次挥手)
大白话
客户端发送完数据后就发生一个释放报文段告诉服务器端我数据发完了,我们可以断开连接了;服务器端收到请求后会立刻告诉客户端,我收到请求了,但是你要等我处理完数据;服务端处理完数据之后,发送释放报文段给客户端,我数据处理完毕了,我们断开连接吧。客户端收到服务端的释放报文段后给服务器一个确认报文,等待2MSL后进入close状态;服务器收到客户端的确认报文后立即进入close状态
为什么要等待2MSL
确保客户端的最后一次报文能够到达服务器
报文段可能在发送的过程中丢失,服务器端没收到客户端的确认报文,会超时重传结束连接报文段,如果客户端发送完确认报文段就进入close,那么服务端就一直拿不到客户端的确认报文,白白等待浪费资源
保证在本次连接过程中的所有报文段从网络中消失,不会影响到下一次连接
tips:
MSL
是最长报文段寿命