简单总结几个个人觉得较为重要的TCP状态。

名词定义:
- 客户端:发起connect操作的端
- 服务端:发起bind操作的端
- 主动关闭端:主动发起四次挥手端
- 被动关闭端:被动接收四次挥手FIN报文端
CLOSED
- 客户端发送SYN后进入SYN_SENT,若超时未收到ACK,则进入CLOSED
- 被动关闭端接收到FIN后,发送ACK后进入CLOSE_WAIT,等待应用可进入CLOSED状态后,发送FIN后进入LAST_ACK状态,等待并接收到主动关闭端的ACK后进入CLOSED状态
- 主动关闭端接收到FIN后,进入TIME_WAIT,等待2MSL时间后,进入CLOSED状态
- 通过设置SO_LINGER可干预内核对于socket close动作的静默处理
CLOSE_WAIT
若程序有大量socket进入此状态,则意味着被动关闭端大量的连接在收到FIN后,程序没有主动将socket close掉。对应到Java的Mina或Netty框架,应该在IDLE或者EXCEPTION_CAUGHT时,主动将socket进行close。
FIN_WAIT
- FIN_WAIT-1是主动关闭端发送FIN后进入的状态
- 主动关闭端若收到被动关闭端ACK,则进入FIN_WAIT-2

服务端的SYN_RCVD与ESTABLISHED
- 服务端处于SYN_RCVD的Socket存在于服务端的半连接队列中,队列数量配置内核参数tcp_max_syn_backlog。臭名昭著的SYN Flood攻击便是利用TCP服务端的SYN_RCVD状态进行攻击的(服务端静默重发ACK五次),半连接队列满了之后,静默处理是拒绝接受新的SYN,攻击者由此达到了拒绝服务攻击的目的,可通过Linux的SYNcookie防范此攻击(此时tcp_max_syn_backlog值无效)
- 服务端处于ESTABLISHED的Socket存在于服务端的全连接队列,队列数量配置内核参数backlog,队列满了将拒绝接受accept新连接,可配置内核参数设置队列满之后静默丢弃客户端的ACK还是发送回一个RST

网友评论