1

众所周知,它getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &opt_val, &opt_len);返回之前分配的 tcp 缓冲区大小的两倍setsockopt()

(如写在man 7 tcp

Note that TCP actually allocates twice the size of the buffer requested in the setsockopt(2) call, and so a succeeding getsockopt(2) call will not return the same size of buffer as requested in the setsockopt(2) call. TCP uses the extra space for administrative purposes and internal kernel structures,)

所以如果我这样做setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (int *)&buf_size, sizeof(buf_size))buf_size = 256K512K就会被分配并返回getsockopt()

我想计算tcp buffer. 为此,我正在计算队列 ( sk->sk_write_queue->len) 中每个数据包的长度,而skis struct sock *sk

碰巧有时返回的长度大于256K. (例如,我得到294879的字节32735数大于256K)。

为什么会发生?它包括"extra space for administrative purposes and internal kernel structures"作为getsockopt(.., SOL_SOCKET, SO_SNDBUF, ..)?

谢谢。

4

1 回答 1

3

由于实际分配了 512K,因此缓冲 294879 字节也就不足为奇了。在 linux 上,当您设置 SO_SNDBUF 时,内核只会将该数量翻倍。

如果您希望套接字缓冲区为 256k,请使用 128k 调用 setsockopt()。

现在,使用的缓冲区不仅仅用于您的数据,内核需要的 skb 和其他数据结构都分配在这些缓冲区中,这是“管理开销”,这相当于多少开销取决于内核如何对数据进行切片你给它 - 所以只为你从用户空间发送的数据保留 256k 的缓冲区空间是一项相当困难的任务,如果不是实际上不可能的话。

于 2013-10-29T08:29:56.530 回答