gpt4 book ai didi

c++ - 设置 SO_RCVBUF 减小窗口比例因子

转载 作者:可可西里 更新时间:2023-11-01 02:46:22 28 4
gpt4 key购买 nike

我有一个用 C++ 编写的小型 Android 应用程序,它打开一个到我的 HTTP 服务器的 TCP 套接字 (python -m SimpleHTTPServer) 并发送一个 header 。无需进一步配置,这是设备发送的 SYN:

Transmission Control Protocol, Src Port: 47262 (47262), Dst Port: 8000 (8000), Seq: 0, Len: 0
Source Port: 47262
Destination Port: 8000
[Stream index: 47]
[TCP Segment Len: 0]
Sequence number: 0 (relative sequence number)
Acknowledgment number: 0
Header Length: 40 bytes
Flags: 0x002 (SYN)
Window size value: 65535
[Calculated window size: 65535]
Checksum: 0x54cb [validation disabled]
Urgent pointer: 0
Options: (20 bytes), Maximum segment size, SACK permitted, Timestamps, No-Operation (NOP), Window scale
Maximum segment size: 1460 bytes
TCP SACK Permitted Option: True
Timestamps: TSval 3637366, TSecr 0
No-Operation (NOP)
Window scale: 7 (multiply by 128)

窗口大小为 65,535,窗口比例因子为 7,因此客户端隐式表示其接收缓冲区为 65,535 * 2 ^ 7 = 8,388,480。

现在,我将以下行添加到代码中:

unsigned long receive_buffer_size = 65535*127;
res = setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &receive_buffer_size, sizeof(receive_buffer_size));

这些行出现在使用 socket() 打开套接字之后,但在使用 connect() 将其连接到端口之前。

我认为这不会影响接收缓冲区,因为我们提供的值与默认设置的值相同。然而,结果如下:

Transmission Control Protocol, Src Port: 47263 (47263), Dst Port: 8000 (8000), Seq: 0, Len: 0
Source Port: 47263
Destination Port: 8000
[Stream index: 2]
[TCP Segment Len: 0]
Sequence number: 0 (relative sequence number)
Acknowledgment number: 0
Header Length: 40 bytes
Flags: 0x002 (SYN)
Window size value: 65535
[Calculated window size: 65535]
Checksum: 0xcf44 [validation disabled]
Urgent pointer: 0
Options: (20 bytes), Maximum segment size, SACK permitted, Timestamps, No-Operation (NOP), Window scale
Maximum segment size: 1460 bytes
TCP SACK Permitted Option: True
Timestamps: TSval 3698768, TSecr 0
No-Operation (NOP)
Window scale: 5 (multiply by 32)

接收缓冲区已减少到 65,535 * 2 ^ 5 = 2,097,120。这怎么解释?

在设置参数前后,我使用以下行写入 SO_RCVBUF:

res = getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &curr_value, &optlen);

在设置参数之前,SO_RCVBUF 为 1,048,576 - 远不及我们在第一个 snif 中看到的默认值。之后,它是 2,097,152,这不是我使用 setsockopt() 提供的。最后一个数字与我们在第二个 snif 中看到的数量级相同,所以至少那里有一些一致性。

请注意,对于每次调用,res 都是正数,因此 getsockopt()setsockopt() 总是成功。

我可以理解操作系统对设置 SO_RCVBUF 有限制,但为什么低于默认值?为什么在设置任何值之前读取 SO_RCVBUF 会导致低于默认值的值?

最佳答案

SYN 段的实际窗口大小不受缩放影响。例如。在您的示例中,它恰好等于 65535,而不是您计算的 8,388,480。这是因为客户端还不知道接收端是否支持窗口缩放。窗口缩放字段的作用类似于发送端支持窗口缩放的通知,并且进一步段的窗口大小必须计算为 window_size<<window_scale .

例子:

  1. 客户端发送“窗口大小值”=29200,“窗口比例”=7 的 SYN。此时实际窗口大小为 29200。
  2. 客户端收到ACK,SYN
  3. 客户端发送“窗口大小值”=229 的 ACK。实际窗口大小等于 229 * 2^7 = 29312。

因此,您需要查看更多 segmentation 以找出实际窗口大小。

关于c++ - 设置 SO_RCVBUF 减小窗口比例因子,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35309975/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com