- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有一个用 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
.
例子:
因此,您需要查看更多 segmentation 以找出实际窗口大小。
关于c++ - 设置 SO_RCVBUF 减小窗口比例因子,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35309975/
为了最小化延迟(我不关心数据包丢失),我想要尽可能小的 UDP 接收缓冲区。但是,当我将 SO_RCVBUF 设置为低于 1000(使用 setsockopt)时,我的程序从未收到任何数据包。我发送的
我有一个用 C++ 编写的小型 Android 应用程序,它打开一个到我的 HTTP 服务器的 TCP 套接字 (python -m SimpleHTTPServer) 并发送一个 header 。无
我正在制作一个程序,该程序创建一个 RAW 套接字以读取所有流量。在调用 socket() 和 recvfrom() 之间(最后一个在循环中以从缓冲区中取出所有数据包)我等待 5 秒。 当我运行该程序
快速提问,想知道是否有人知道 Windows 下 SO_RCVBUF 的限制是多少。 最佳答案 winsock 中的SO_RCVBUF 不受TCP 窗口大小的限制。至少对于 pre-Vista 堆栈。
你能解释一下 SO_SNDBUF 和 SO_RCVBUF 选项到底是什么吗? 好的,出于某种原因,操作系统会缓冲传出/传入数据,但我想澄清一下这个问题。 他们的角色(通常)是什么? 它们是每个套接
我有一个系统,当发生某些情况时,单字节消息会通过 UDP 套接字从一个进程发送到另一个进程。在接收端,这个事件发生一次、十几次甚至一百万次并不重要。 我想也许我可以使用setsockopt将SO_RC
我在 Linux 机器上有超过 300 万个文件描述符,所以我查看了套接字缓冲区大小与 RAM 大小的关系如何限制机器可以处理的最大同时 tcp 连接数。有没有类似经历的,请指教。谢谢。 最佳答案 这
我有一个在 Windows XP 上使用 TCP 的应用程序。当我使用 SO_RCVBUF 选项调用 getsockopt 时,它报告 8192 字节。但是,Wireshark 显示该应用程序通告 6
我接受一个带有默认值的 TCP 连接,我观察到 SYN、ACK 以 64K 的窗口大小和 7 的窗口比例因子发送。 在 3 次握手完成并为我的应用程序交换一些控制数据包后,我使用 setsockopt
在我的仅基于 LAN 的应用程序中,增加传输和接收缓冲区对性能有很大影响。 在 Linux 下,我可以将发送和接收缓冲区增加到 262142 字节。 是否可以在不更改内核的情况下绕过此限制?我正在使用
谁能快速解释一下 Netty/NIO 如何从操作系统消耗 TCP 缓冲区? 我认为 TCP 滑动窗口 ACK 由操作系统 TCP 堆栈(recvspace)管理,并在每个数据包(MTU 大小)之后发回
我需要读取最近传入的 UDP 数据包,无论读取之间是否丢失了数据包。传入数据包的速度比最大应用程序处理速度快 3 倍。为了实现这一目标,我使用 Java 的 DatagramSocket 类的 set
我在 C 程序中向 250 个节点发送 icmp 回显。套接字是这样创建的 sfd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP); 我有 getsockopt S
我是一名优秀的程序员,十分优秀!