4.3 TCP 实战抓包分析
tcpdump 和 Wireshark 就是最常用的网络抓包和分析工具,更是分析网络性能必不可少的利器。
- tcpdump 仅支持命令行格式使用,常用在 Linux 服务器中抓取和分析网络包。
- Wireshark 除了可以抓包外,还提供了可视化分析网络包的图形页面。
所以,这两者实际上是搭配使用的,先用 tcpdump 命令在 Linux 服务器上抓包,接着把抓包的文件拖出到 Windows 电脑后,用 Wireshark 可视化分析。
当然,如果你是在 Windows 上抓包,只需要用 Wireshark 工具就可以。
TCP 三次握手异常情况实战分析
在linux中
TCP 第一次握手的 SYN 丢包了,会发生了什么?
- 客户端会重传,每次超时时间 RTO 是指数(翻倍)上涨的,当超过最大重传次数后,客户端不再发送 SYN 包。
- 最大重传次数可以在 /proc/sys/net/ipv4/tcp_syn_retries 设置,默认五次
TCP 第二次握手的 SYN、ACK 丢包了,会发生什么?
- 和上面的操作是相同的,会发生超时重传
TCP 第三次握手的 ACK 包丢了,会发生什么?
- 服务端会重传SYN、ACK 包直到最大次数,之后还没有收到ACK包就会主动断开TCP连接
- 客户端也会重传确认报文达到最大次数,这个次数是由 /proc/sys/net/ipv4/tcp_retries2 文件参数指定的(默认15次)
- 因为客户端处于established状态,会触发 保活机制:如果一段时间内TCP连接没有任何连接相关的活动,会每隔一段时间发送一个数据很少的探测报文,如果连续几个探测报文都没有得到响应,则认为当前的 TCP 连接已经死亡,系统内核将错误信息通知给上层应用程序。
- 如果客户端不发数据包,默认可能需要经过 2 小时 11 分 15 秒才可以发现一个「死亡」连接
TCP 快速建立连接
客户端在向服务端发起 HTTP GET 请求时,一个完整的交互过程,需要 2.5 个 RTT 的时延。
由于第三次握手是可以携带数据的,这时如果在第三次握手发起 HTTP GET 请求,需要 2 个 RTT 的时延。
但是在下一次(不是同个 TCP 连接的下一次)发起 HTTP GET 请求时,经历的 RTT 也是一样,如下图:

在 Linux 3.7 内核版本中,提供了 TCP Fast Open 功能,这个功能可以减少 TCP 连接建立的时延。

- 在第一次建立连接的时候,服务端在第二次握手产生一个
Cookie(已加密)并通过 SYN、ACK 包一起发给客户端,于是客户端就会缓存这个Cookie,所以第一次发起 HTTP Get 请求的时候,还是需要 2 个 RTT 的时延; - 在下次请求的时候,客户端在 SYN 包带上
Cookie发给服务端,就提前可以跳过三次握手的过程,因为Cookie中维护了一些信息,服务端可以从Cookie获取 TCP 相关的信息,这时发起的 HTTP GET 请求就只需要 1 个 RTT 的时延;
注:客户端在请求并存储了 Fast Open Cookie 之后,可以不断重复 TCP Fast Open 直至服务器认为 Cookie 无效(通常为过期)
在 Linux 上如何打开 Fast Open 功能?
可以通过设置 net.ipv4.tcp_fastopn 内核参数,来打开 Fast Open 功能。
