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连接。建议应处理好程序代码。
You need to set
install_url
to use ShareThis. Please set it in _config.yml
.