TCP协议的三次握手和四次挥手过程

学习记录来源:《32个Java面试必考点》

三次握手建连过程:

在这里插入图片描述

  1. 首先在建立连接前需要让Server端先监听端口。因此,Server端建立连接前的初始状态是listen状态
  2. 这时Client端准备建立连接,先发送一个SYN同步包,发送完同步包后,Client端的连接状态为syn_sent状态
  3. Server端收到SYN后,同意建立连接,会向Client端回复一个ACK,由于TCP是双工传输,Server端也会向Client端同时发送一个同步请求SYN,申请Server端向Client端建立连接。发送完ACK和SYN后,Server端的状态就变成了syn_rcvd(syn_received)
  4. Clinet收到Server的ACK后,Client的连接状态就变成了established的状态。同时,Client端向Server端发送ACK响应,回复Server端的SYN请求。
  5. Server端收到Client端的ACK后Server端的连接状态就变成了established的状态。
    此时,建连完成,双方随时进行数据传输。
  • 三次握手是为了建立双向连接
  • 需要记住Client端和Server端的连接状态变化
  • 回答SYN洪水冲击发生的原因:Server端在收到Client端的SYN请求后,发送了ACK和SYN,但是Client端不进行回复,导致Server端大量的连接处在syn_rcvd状态,进而影响其它正常请求的建连
  • 上面解决:可以设置Linux的TCP参数,syc_ack_retries=0来加快半连接的回收速度.或者调大max_syn_backlog来应对少量的SYN洪水攻击。
四次挥手断连过程:

在这里插入图片描述

  1. 首先通信的双方(Server和Client)起初都是established的状态
  2. 然后Client端先发起了关闭链接请求。Client端向Server端发起了一个FIN包,表示Clinet端已经没有数据要发送了,然后Client端就进入了fin_wait_1状态。
  3. Server端收到FIN后,返回ACK。然后进入close_wait状态,此时,Server处于半关闭状态。因为此时Client向Server方向已经不会发起数据了,但是Server向Client可能还有数据要发送。当Server端数据发送完毕后,Server端会向Client端发送FIN,表示Server端也没有数据要发送了,这时,Server进入last_ack阶段,就等待Clinet端的应答就可以关闭连接了。
  4. Client端收到Server端的FIN后,回复ACK,然后进入time_wait状态。time_wait状态下,需要等待两倍的MSL,就是最大报文段生存时间,来保证连接的可靠关闭,之后才会进入到closed状态
  5. 而Server端在收到ACK后就直接可以进入到closed状态。
  • 为什么要等待两倍的MSL之后才能关闭连接?
    原因有2个:
    1.要保证TCP协议的全双工连接能够可靠关闭
    2.要保证这次连接中重复的数据段能够从网络中消失,防止端口被重用的时候,可能会产生数据混淆
  • 大量Socket处于time_wait或者close_wait状态的问题?
    一般开启Linux的TCP参数tw_reuse和tw_recycle能够加快time_wait的回收
    而出现在量的close_wait状态,一般是被动关闭的一方,可能存在代码的bug,没有正确关闭连接所导致的
原文地址:https://www.cnblogs.com/dulinan/p/12033005.html