示意图
流程概述
前置概念
Seq:TCP第一次握手时随机生成的初始序列号,表示数据的起始位置;
SYN:同步序号标志,SYN报文用来发起连接请求,TCP规定该报文不能携带数据,但仍然需要消耗一个序号;相当于告诉对方“嘿,我想和你建立连接”,类似于生活中去别人家做客时轻敲对方的大门。
ACK:确认同步序号标志,ACK报文用于确认接收到对方发送的信息,TCP规定该报文可以不携带数据,并且不携带数据时不消耗序号;相当于告诉对方“我已经接收到你的请求了”,类似于房子主人听到拜访者敲门时回应对方一句“来了来了”。
第一次握手
客户端(Client)发送一个SYN数据包给服务器请求建立TCP连接,该数据包包含客户端随机生成的初始序列号Seq,假设Seq=x,其格式大致为:
SYN flag = 1,Seq = x,ACK flag = 0
假设这部分数据为:
SYN = 1,Seq = 1000,ACK = 0
第二次握手:
服务器(Server)接收到建立连接的请求后,会回应一个SYN-ACK数据包给客户端表明已经接收到请求,但是还需要对方回应确认下。同时给出自己的初始序列号Seq,假设Seq = y,其格式大致为:
SYN flag = 1,Seq = y,ACK flag = 1,Ack = x + 1【SYN报文需要消耗一个序号,因此需要+1】
假设这部分数据为:
SYN = 1,Seq = 2000,ACK = 1,Ack = 1001
第三次握手:
客户端接收到服务器的SYN-ACK数据包后,知道服务器收到并同意建立连接的请求,但还要回应一个ACK数据包给服务器。服务器接收后TCP连接就算建立起来了。其格式大致为:
SYN flag = 0,Seq = x + 1,ACK flag = 1,Ack = y + 1
假设这部分数据为:
SYN = 0,Seq = 1001,ACK = 1,Ack = 2001
为什么需要三次握手,而不是两次?
三次握手能够确认客户端和服务器双方的序列号,类似于发送请求并得到应答的流程。但是两次握手仅是客户端发送序列号给服务端,服务端确认了客户端的序列号,而服务端的序列号却没有得到确认。因此,需要经过第三次握手也确认下服务端的序列号。
是否可以进行四次握手?
可以进行四次握手建立连接,但是该过程会更耗时,为了提高效率,三次握手即可。