c - 非零 TCP 窗口比例选项的原因

标签 c linux networking tcp linux-kernel

我读了一些关于 TCP window scaling 的东西和 BDP (不太清楚),我无法弄清楚到底是什么原因导致发送方的 TCP 实现设置非零 WS,用户模式客户端程序是否会以某种方式影响它?我认为从逻辑上讲它不能基于某些数据传输,因为它发生在 SYN-SYN+ACK TCP 阶段。

有人可以从编程的角度解释一下,用户模式客户端代码如何影响 TCP 窗口缩放选项(例如,在 connect() 调用之前)? TCP 堆栈如何知道何时将 WS 设置为非零值?

抱歉,如果显而易见。

最佳答案

TCP 窗口缩放索引 rcv_wscale(例如,在发送 SYNSYN-ACK 时)是在 Linux 内核中基于套接字的接收缓冲区计算的在函数中 tcp_select_initial_window() :

/* If no clamp set the clamp to the max possible scaled window */
if (*window_clamp == 0)
    (*window_clamp) = (65535 << 14);
space = min(*window_clamp, space);

/* Quantize space offering to a multiple of mss if possible. */
if (space > mss)
    space = (space / mss) * mss;
//...
(*rcv_wscale) = 0;
if (wscale_ok) {
    /* Set window scaling on max possible window
     * See RFC1323 for an explanation of the limit to 14
     */
    space = max_t(u32, space, sysctl_tcp_rmem[2]);
    space = max_t(u32, space, sysctl_rmem_max);
    space = min_t(u32, space, *window_clamp);
    while (space > 65535 && (*rcv_wscale) < 14) {
        space >>= 1;
        (*rcv_wscale)++;
    }
}

这里的space取自tcp_full_space()基于sk_rcvbuf

知道您可以通过更改接收缓冲区的大小来影响此计算:

int buflen = 12345;
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &buflen, sizeof int) < 0)
    perror("setsockopt():");
//...

这可以为您提供零缩放(WS=0wscale 0)。

附言请记住,在服务器端,它应该在监听套接字上完成,因为在 TCP 握手之后你不能影响它。

关于c - 非零 TCP 窗口比例选项的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58122062/

相关文章:

networking - Kubernetes 服务部署

mysql - Amazon Web Service RDS 连接失败

c - 多线程 C 应用程序中的访问冲突

c - 在 C 中使用系统调用编写填充十六进制

c - 从 create_proc_read_entry 迁移到 proc_create 并使用 seq_files

linux - 重定向到 bash 中存储 awk 的变量

c - 解决由 valgrind 检查的内存问题

linux - Ansible scp 错误 - 没有这样的文件或目录

linux - 如何从 awk 命令中删除填充?

Java - 简单的网络游戏非常滞后