Skip to content

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 也是一样,如下图:

常规 HTTP 请求

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

常规 HTTP 请求 与 Fast  Open HTTP 请求

  • 在第一次建立连接的时候,服务端在第二次握手产生一个 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 功能。

正在精进