tcp缓冲区中的总包长度是否超过分配的缓冲区大小?

时间:2013-10-29 07:41:37

标签: c linux networking tcp linux-kernel

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

(正如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 = 256K 512K,则会getsockopt()分配并返回tcp buffer

我想计算sk->sk_write_queue->len中的当前字节数。为此,我计算队列中每个数据包的长度(sk),struct sock *sk256K

有时候返回的长度大于294879。 (例如,我得到的32735个字节比256K"extra space for administrative purposes and internal kernel structures"个字节。)

为什么会这样? 它是否包含getsockopt(.., SOL_SOCKET, SO_SNDBUF, ..)作为{{1}}?

感谢。

1 个答案:

答案 0 :(得分:3)

由于512K实际上已经分配,​​缓冲294879字节并不令人惊讶。 在linux上,当您设置SO_SNDBUF时,内核只会将该数量加倍。

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

现在,使用的缓冲区并不纯粹是针对您的数据,内核需要的skb和其他数据结构都是在这些缓冲区中分配的,这就是“管理开销”,这相当于多少开销取决于内核切片的方式你给它的数据 - 所以只为你从用户空间发送的数据保留256k的缓冲空间是一项相当困难的工作,如果不是几乎不可能的话。