TCP

[toc]

正常情况下的TCP连接状态流程

连接建立:
三次握手:
  • CLOSED: 初始关闭状态。
  • LISTEN: 服务端监听状态,等待客户端连接。
  • SYN_RCVD: 服务端接收到客户端的SYN报文,发送SYN+ACK返回客户端后进入该状态等待客户端的ACK。
  • SYN_SENT: 客户端发送SYN给服务端后进入该状态,等待接受服务端的SYN+ACK。
连接中:
  • ESTABLISHED: 连接已经建立,传输数据。
连接关闭:
主动关闭方状态:
  • FIN_WAIT_1: 主动发送FIN给对方后,进入该状态等待对方的ACK。
  • FIN_WAIT_2:接收到对方发来的对于第一个FIN的ACK后进入这个状态。此时程序仍可以接受对方发来的数据,直到对方发来FIN。
  • TIME_WAIT: 接收到了对方的FIN后,返回ACK并进入该状态,等待2*MSL时间,防止对方没有接收到ACK,以便再重发ACK(另一端超时并重发FIN)。维持连接一段时间防止被其他程序复用。
被动关闭方状态:
  • CLOSE_WAIT: 接收到对方发来的FIN之后,返回ACK并进入该状态,此时可以进行未完的数据传输,然后关闭连接,发送FIN给对方后就进入LAST_ACK状态。
  • LAST_ACK: 发送FIN给对方后等待其ACK的过程,当接受到ACK后就转回CLOSED了。
双方共同关闭连接状态:
  • CLOSING: 双方都发FIN包给对方,接收到后各自返回ACK,并都从FIN_WAIT_1进入该状态,等待对方的ACK包,接收到各自的ACK包便进入TIME_WAIT状态。

异常情况下的TCP连接状态

SYN_RCVD

建立连接的时候,客户端发送SYN给服务端,服务端接受后返回SYN+ACK并进入SYN_RCVD状态等待。如果此时客户端掉线或恶意不返回ACK包,那么服务端会持续等待并重发直到超时。如果有大量的该情况发生,如果SYN半开连接队列已满,耗尽资源,无法应对正常的客户端连接,这种攻击方法就叫做SYN FLOOD。

FIN_WAIT2

在该状态下,我们已经发送了FIN并收到了ACK,但对方不发送FIN过来,此时如果客户端程序已关闭,没有程序在使用这个SOCKET,那么操作系统会等待默认60s,(net.ipv4.tcp_fin_timeout),然后直接将该连接转为CLOSED。

CLOSE_WAIT

一般情况下,大量出现该状况可能是,程序代码出现问题,没有close socket或者是响应时间太慢,或者对方超时选项太短,导致对方已中断,而本地连接停留在CLOSE_WAIT状态,由于该状态没有生命周期定义,如果不结束进程,会一直存在,或者如果KEEPALIVE机制启用,接收到对方的RST后结束连接。

TIME-WAIT

首先注意TIME-WAIT永远只出现在主动断开连接的一方。如果大量出现该状态,一般是短时间大量并发短链接导致,不能随意按照网上所说修改内核参数tcp_tw_reuse或者tcp_tw_recycle,会造成大量诡异问题,甚至直接无法建立TCP连接。建议应处理好程序代码。

作者

XMoon

发布于

2022-10-26

更新于

2022-10-26

许可协议

You need to set install_url to use ShareThis. Please set it in _config.yml.

评论

You forgot to set the shortname for Disqus. Please set it in _config.yml.