c - tcp 缓冲区中的总数据包长度是否可以超过分配的缓冲区大小?

标签 c linux networking tcp linux-kernel

众所周知,getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &opt_val, &opt_len); 返回之前在 setsockopt().

(如 man 7 tcp 中所写:

请注意,TCP 实际上分配了请求缓冲区大小的两倍 setsockopt(2) 调用,因此后续的 getsockopt(2) 调用将不会返回与 setsockopt(2) 调用中请求的相同大小的缓冲区。 TCP 将额外空间用于管理目的和内部内核结构,)

所以如果我执行 setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (int *)&buf_size, sizeof(buf_size)) for buf_size = 256K, 512K 将在 getsockopt() 中分配和返回。

我想计算tcp 缓冲区 中的当前字节数。为此,我正在计算队列中每个数据包的长度 (sk->sk_write_queue->len) 而 skstruct sock *sk.

有时返回的长度大于256K。 (例如,我得到的 294879 字节比 256K32735 字节)。

为什么会这样? 它是否包含 “用于管理目的和内部内核结构的额外空间” 作为 getsockopt(.., SOL_SOCKET, SO_SNDBUF, ..)

谢谢。

最佳答案

由于实际分配了 512K,缓冲 294879 字节并不奇怪。 在 Linux 上,当您设置 SO_SNDBUF 时,内核只会将该数量加倍。

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

现在,所使用的缓冲区不纯粹是为了你的数据,内核需要的skb和其他数据结构都分配在这些缓冲区中,这就是“管理开销”,这相当于多少开销取决于内核如何切片增加你给它的数据——所以只为你从用户空间发送的数据保留 256k 的缓冲区空间是一个相当困难的任务,即使不是几乎不可能完成的任务。

关于c - tcp 缓冲区中的总数据包长度是否可以超过分配的缓冲区大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19652356/

相关文章:

C 到 Delphi 翻译

c - 位图最大尺寸

c - 在 c 中暂停 posix 线程特定时间间隔的问题

linux - 将 "file"linux 命令应用于 Perl 中的二进制缓冲区

linux - 如何在编译时禁用 glibc 中的 AVX512 和/或 AVX2?

networking - TCP 和 Go Back N 的区别

Java 代理设置

c - 如何求解 4 个变量的方程

c++ - 如何访问RTCVideoRenderer的帧? (ios)

java - 将 Java 程序从 UDP 切换到 TCP 的最简单方法是什么?