参考视频链接:b站蛋老师视频链接
握手机制的核心:怎样的握手能判断出那些请求或者哪些响应需要丢弃,并不是只能三次握手,而是至少三次握手才能保证。
TCP报文中有:SYN(synchronization 同步的意思),ACK(acknowledgment 确认的意思),FIN(finish 结束的意思)等标识,如果设置为1则为开启,设置为0则为关闭。
三次握手:
1.客户端开启SYN,表示想和服务端进行数据的同步,并生成一个序号A,同步以后(即三次握手之后,客户端就可以和服务端互相发送消息);
2.服务器收到SYN,做出响应:在TCP报文中把SYN和ACK开启(确认同步),服务器也生成一个序号B,并生成一个确认号为客户端的序号A+1;
3.客户端收到SYN和ACK以及服务器生成的序号B、确认号(A+1),通过确认号-1对比自身的序号,就可以知道握手的对象对不对,再通过服务端给到的序号B和确认号A+1生成自己的序号和确认号,客户端向服务端发送,开启ACK标识,序号为服务端的确认号,确认号为服务端的序号+1;
注:如果每次客户端发送SYN,服务器都记住其序号并生成自己需要记住的序号,那服务器需要挂起很多资源,如果有黑客不断发送SYN又不进行下一步,服务器会原地崩溃(DDoS攻击 ),所以服务器不保存自己的序号,根据服务器的ip、端口号等私有信息进行运算得到序号。
在握手的过程中,两端可以根据序号、确认号,或者控制位(1.SYN,2.SYN+ACK,3.ACK)来区分进行到哪一个步骤,丢弃一些不必要的报文。
握手之后就建立了连接,客户端就可以发送HTTP请求了,然后服务器做出响应。
假设两端交互完毕,各自可能发起关闭连接的要求(四次挥手)(客户端、服务端都能主动发起关闭请求)。
四次挥手:
假设客户端主动发起关闭要求:
1.客户端开启FIN和ACK两个控制位,此时序号和确认号不用固定数字表示;
2.服务端先发送ACK确认,服务端生成序号、确认号的过程与握手时一致;
3.此时客户端不会直接关闭通道,也许服务端还有需要发送的数据,等服务端发送完之后,会再发送一个FIN+ACK进行最后确认,此时序号、确认号不需要改变。
4.客户端得到服务端最终的确认,发送ACK进行确认,生成序号与确认号规则与握手时一致;
为什么需要至少四次挥手:可能存在未发送完毕的数据。