TCP窗口规模选项不为零的原因

1 人关注

我读了一些关于 TCP窗口的缩放比例 BDP (not quite clear),和I can't figure out what exactly cause sender's TCP realization to set non-zero WS和could the user-mode client program affect it somehow? I think that logically it cannot be based on some data transferring because it happens on SYN-SYN+ACK TCP stage.

谁能从编程的角度解释一下,用户模式的客户端代码如何影响TCP窗口规模选项(例如在 connect() 调用之前)?以及TCP协议栈如何知道何时将WS设置为非零?

Sorry if obvious.

c
linux
networking
tcp
linux-kernel
narotello
narotello
发布于 2019-09-27
1 个回答
red0ct
red0ct
发布于 2019-10-04
已采纳
0 人赞同

TCP窗口的缩放指数 rcv_wscale (例如,在发 SYN or 呼叫中心(SYN-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是在sk_rcvbuf的基础上取自tcp_full_space()

知道你可以通过改变接收缓冲区的大小来影响这个计算。

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