一文理解TCP连接状态

1. linux查看TCP状态

  • netstat -nat : 查看TCP链接的状态
  • lsof -i:port 查看打开套接字的状态
  • tcpdump -Xns0 -i any tcp port 20789

2. TCP状态转换

一共11种状态

TCP状态转换图

2.1 客户端状态迁移

CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED

2.2 服务端状态迁移

CLOSED->LISTEN->SYN_RCVD->ESTABLISTED->CLOSE_WAIT->LAST_ACK->CLOSED

3 TCP三次握手状态

3.1 正常打开

  • 客户端:CLOSED(socket创建)---> SYN_SENT(connect阻塞调用,发送SYN)----> ESTABLISHED(connect返回,接收:SYN,ACK,发送:ACK)
  • 服务端:CLOSED(socket创建)---> LISTEN(bind,listen被动打开) --->SYN_RCVD(accept阻塞) ---> ESTABLISTED(accept返回,接收:SYN,发送:SYN,ACK)

握手过程

TCP三次握手过程

状态转换

正常三次握手状态转换

3.2 同时打开

  • 在SYN_SENT状态收到SYN变为SYN_RCVD状态,再收到ACK变为ESTABLISTED
  • 代码中两边同时调用CONNECT?

握手过程

TCP同时打开握手过程

状态转换

TCP同时打开握手状态

3.3 连接超时或者RST复位

  • 客户端发送SYN后,没有收到服务端响应,重试net.ipv4.tcp_syn_retries(6次)后超时回到CLOSED状态

1+2+4+8+16+32+64=127

  • 服务端发 SYN+ACK后,重试net.ipv4.tcp_synack_retries回到LISTEN状态
  • 客服端connect之后立马调用close,服务端发送SYN,ACK后会收到客户端内核返回的一个RST

握手过程

状态转换

image.png

4. 四次挥手

4.1 正常关闭

  • 客户端: ESTABLISTED -->FIN_WAIT_1(调用CLOSE,发送FIN) -->FIN_WAIT_2(收到服务端ACK)-->TIME_WAIT(收到FIN) --> CLOSED(2msl后)
  • 服务端:ESTABLISTED-->CLOSE_WAIT(read返回0,收到FIN,发送ACK)-->LAST_ACK(调用close,发送FIN)-->CLOSED(收到ack)

挥手过程

四次挥手过程

状态转换

四次挥手状态转换

4.2 同时关闭

  • 在FIN_WAIT_1状态接受到一个FIN,进入CLOSING,用于等待ACK,收到后进入CLOSE_WAIT状态
  • 客户端、服务端同时调用close

挥手过程

TCP同时挥手

状态转换

同时挥手状态转换

4.3 四次挥手合并为三次挥手

  • 服务端同时发送FIN+ACK,导致客户端直接公FIN_WAIT_1进入TIME_WAIT状态
  • 一般是因为内核ACK确认延迟,同FIN包一起返回

挥手过程

三次挥手

状态转换

三次挥手状态
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容