tcp_autocork_mss如何MSS

联启 网络工具 13

本文目录导读:

tcp_autocork_mss如何MSS-第1张图片-电脑手机工具软件下载 - 免费实用工具合集 | 联启科技

  1. 核心概念:自动 Corking 与 MSS 阈值
  2. 如何通过 MSS 阈值控制它?
  3. 它与实际 MSS 大小(MSS Cache)的关系
  4. 总结:如何通过 MSS 进行控制?
  5. 代码层面的实现(内核源码参考)
  6. 实践建议

在 Linux 内核中,tcp_autocorking 与 MSS (Maximum Segment Size,最大报文段长度) 的交互,主要是通过一个名为 tcp_autocork_mss 的阈值来实现的。

tcp_autocork_mss 并不是直接设置 MSS 的大小,而是设置一个 MSS 数量 的阈值,用于决定是否触发自动 Cork(塞子)机制。

下面我们来详细拆解这个机制和 MSS 的关系:

核心概念:自动 Corking 与 MSS 阈值

  1. 自动 Corking 的作用:当应用程序多次调用 send() 发送小块数据时,内核不会立即发送每个小块,而是将它们暂存在发送缓冲区中,等待累积到一定量后再一次性发出,这可以减少小包(尤其是纯 ACK 包)的数量,提高网络吞吐量。

  2. tcp_autocork_mss 的含义

    • 它不是一个绝对值(1460 字节)。
    • 它是一个 MSS 的倍数
    • 默认值是 0,当值为 0 时,自动 Corking 被禁用。
    • 生效机制:当内核决定是否开始“自动塞子”时,它会检查一个条件,在 tcp_sendmsg()tcp_push() 等函数中,内核会检查:如果发送缓冲区中已经有数据,并且这些数据的长度加上新写入的数据长度,除以 tcp_sk(sk)->mss_cache 得到的整数部分大于或等于 1,那么就会触发自动 Corking。

    这个逻辑可以简化理解为:如果当前待发送的数据量已经超过了一个 MSS,内核会认为值得开启 Cork 来合并后续的写入。

如何通过 MSS 阈值控制它?

在 Linux 内核中,这个阈值是通过 sysctl 参数 net.ipv4.tcp_autocork_mss 来设置的。

  • 获取当前值

    sysctl net.ipv4.tcp_autocork_mss
    # 通常输出: net.ipv4.tcp_autocork_mss = 0 (默认禁用)
  • 修改值

    # 设置为3,意味着当待发送数据达到3个MSS时,才开始自动Corking。
    sudo sysctl -w net.ipv4.tcp_autocork_mss=3

它与实际 MSS 大小(MSS Cache)的关系

实际的 MSS 大小(mss_cache)由连接建立时的 SYN/SYN-ACK 协商决定(通常是 1460 字节,取决于 MTU)。

  • tcp_autocork_mss = 1 时

    • mss_cache = 1460 字节。
    • 只要内核发现缓冲区中已有 > 1460 字节的数据,就会开启自动 Cork,等待后续写入后一次性发送,这通常能很好地平衡延迟和吞吐量。
  • tcp_autocork_mss = 3 时

    • mss_cache = 1460 字节。
    • 内核需要看到缓冲区中已累积 > 3 * 1460 = 4380 字节的数据才触发 Cork,这会强制让应用程序合并更多的写入,但可能会增加单个 TCP 段的发送延迟。

如何通过 MSS 进行控制?

不能直接设置一个“MSS 字节数”作为阈值,内核暴露的控制参数是 tcp_autocork_mss,它是一个 MSS 的计数

  1. 禁用自动 Corkingsysctl -w net.ipv4.tcp_autocork_mss=0
  2. 启用一个保守的策略(最少攒一个 MSS 再发)sysctl -w net.ipv4.tcp_autocork_mss=1 (推荐,平衡延迟和吞吐量)
  3. 启用更激进的合并策略(攒多个 MSS 再发)sysctl -w net.ipv4.tcp_autocork_mss=3 或更高(可能增加延迟,但减少小包)

代码层面的实现(内核源码参考)

在 Linux 内核源码 net/ipv4/tcp.ctcp_should_autocork() 函数中,逻辑大致如下(简化):

static bool tcp_should_autocork(struct sock *sk, struct sk_buff *skb,
                                int size_goal)
{
    struct tcp_sock *tp = tcp_sk(sk);
    int mss = tcp_sk(sk)->mss_cache;
    // sysctl_tcp_autocork_mss 为 0,直接返回 false
    if (!sysctl_tcp_autocork_mss)
        return false;
    // 关键条件:检查发送队列中已有数据的长度
    // 使用 skb_queue_len(&sk->sk_write_queue) 获取队列中 skb 的数量
    // 但更核心的是判断当前累积的字节数是否达到了 mss * sysctl_tcp_autocork_mss
    // 以下是简化版逻辑
    return (tp->write_seq - tp->snd_nxt) > (sysctl_tcp_autocork_mss * mss);
}

实践建议

  • 对于大多数通用场景,保持默认值 0 或设置为 1 是合理的。
  • 如果你的应用是小块写入、高频发送(例如游戏服务器、流媒体),建议设置为 1,可以有效合并小包。
  • 如果你的应用是低延迟优先,且每个 send() 本身就很大,可以保持 0(禁用),避免不必要的等待。
  • 设置的值不要过大,否则会导致发送延迟显著增加,影响交互性,通常不超过 3

一句话总结:tcp_autocork_mss 不是设置 MSS 的字节数,而是设置一个 MSS 的计数阈值,用来控制 TCP 自动塞子机制何时开启。

标签: MSS

抱歉,评论功能暂时关闭!