目录
深刻理解三次握手
深刻理解四次挥手
深刻理解三次握手
- 三次握手时,如果最后一个ACK包,服务器没有收到,此时:
客户端:认为已经建立链接
服务器:认为没有建立链接,还在超时等待。
而此时客户端已经开始发送数据TCP包,则服务器收到数据TCP包后丢弃,发送RST(reset)包,提示客户端请重新建立链接,这个行为叫做重置。
客户端收到RST包,关闭已经建立的链接,重新做三次握手。
- 为什么建立链接是三次握手
如果客户端发起一次请求,服务器就建立链接,这样服务器很容易遭受攻击,因为服务器维护链接是有成本的,而如果客户端无穷无尽的发送包,服务器认为这些包都可以建立链接,大量的维护成本足以让服务器死机。
客户端发送大量请求链接的SYN包,称为SYN洪水攻击,特点是只需要一台客户端就可以做攻击。
而三次握手,虽然也会遭受到SYN洪水攻击,但相比一次、两次握手,三次握手更加可靠许多,因为服务器要求客户端发送ACK包,收到ACK包后,服务器才会建立链接,三次握手下,一定是客户端先建立链接,再是服务器建立链接,这种关系可以保证服务器不会被一台主机做SYN洪水攻击。
- 为什么通信前要三次握手?
1.需要保证网络是通畅的,仔细观察,在三次握手中,双方都进行了一次收发操作,确认客户端、服务器都是全双工的。
2.确保双方的TCP协议栈是健康的,在一次建立链接的过程中,客户端发送SYN包,等待ACK,服务端也是发送SYN包,等待ACK,只不过服务器发送的ACK包做了捎带应答,三次握手本质是四次握手捎带成三次握手。
深刻理解四次挥手
- 四次挥手
当客户端不想再发送数据了,就调用close接口,此时TCP协议栈刷空发送缓冲区,发送FIN报头,并接收ACK报头。
- 如果服务器在收到FIN报头后,也准备关闭链接,则ACK+FIN做捎带应答,只需三次挥手即可。
- 客户端在发送FIN报头后,就已经调用close,那么当服务器发送FIN报头后,客户端是怎么接收的呢
1.TCP协议栈可以调用shutdown接口,使套接字做半双工模式,可以只关闭发送模式,保留接收。
2.实际上,调用close后还需要等待应答,这个tcp套接字的状态为TIME_WAIT,等待FIN报头,响应后才会关闭链接。
- 四次挥手的状态
主要谈TIME_WAIT,等待的时间为2个MSL,发起方一定会进入TIME_WAIT,发起方是率性完成四次挥手的。
- 四次挥手的设计中,为什么要TIME_WAIT
1.客户端发起FIN,收到ACK,其实已经可以关闭链接了,但在实际网络中,往往存在一些遗留的历史包的问题,这些包有极小的概率会影响新链接的通信,而客户端进入TIME_WAIT,可能会等到那些遗留的包,避免历史包的影响。
2.客户端为什么等:在前两次挥手中,如果包出错了,可以重发补救,因为没有任何一方关闭了链接。而在后两次挥手中,客户端如果已经关闭链接了,无法保证服务器能收到ACK响应。在客户端TIME_WAIT的过程中,可以等到服务器的FIN包,保证服务器也完成四次挥手。