TCP 状态机

343 阅读1分钟

TCP 状态机

image.png

image.png

客户端发起的连接请求可能因为各种原因没有回复,这时客户端会做重试。一般在 Linux 里,重试次数默认是 6 次,内核参数是 net.ipv4.tcp_syn_retries。重试间隔遵循了指数退避原则。

服务端拒绝 TCP 握手,除了用 TCP RST,另外一种方式是通过 ICMP Destination unreachable(Port unreachable)消息。从客户端应用程序看,这两种回复都属于“对端拒绝”,所以应用表面看不出区别,但我们在抓包的时候要注意,如果单纯抓取服务端口的报文,就会漏过这个 ICMP 消息,可能对排查不利。

对于连通性相关的问题,除了用 tcpdump+Wireshark 这个黄金组合,我们还可以在理解 TCP 握手原理的基础上,使用小工具(比如 netstat)来排查。特别是对于 RPC 服务场景,在问题发生时及时执行 netstat -ant,找到 SYN_SENT 状态的连接,这个很可能是突破口。

握手包中的 Window Scale 信息十分重要,这会帮助我们知道正确的接收窗口。在分析抓包文件时,要注意是否连接的握手包被抓取到,没有握手包,这个 Window 值一般就不准。