Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
tcp缓冲区中的数据包总长度是否可以超过分配的缓冲区大小?_C_Linux_Networking_Tcp_Linux Kernel - Fatal编程技术网

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

tcp缓冲区中的数据包总长度是否可以超过分配的缓冲区大小?,c,linux,networking,tcp,linux-kernel,C,Linux,Networking,Tcp,Linux Kernel,众所周知,getsockopt(sock,SOL_SOCKET,SO_SNDBUF,&opt_val,&opt_len)返回以前在setsockopt()中分配的tcp缓冲区大小的两倍 (如man 7 tcp中所述: 请注意,TCP实际分配的缓冲区大小是 setsockopt(2)调用,因此后续的getsockopt(2)调用将不会返回与setsockopt(2)调用中请求的相同大小的缓冲区。TCP 将额外空间用于管理目的和内部内核结构,) 因此,如果我对buf\u size=256K执行set

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

(如
man 7 tcp
中所述:

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

因此,如果我对
buf\u size=256K
执行
setsockopt(sock,SOL\u SOCKET,So\u SNDBUF,(int*)和buf\u size,sizeof(buf\u size))
操作,则
512K
将在
getsockopt()
中分配并返回

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

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

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


谢谢。

由于512K实际上已分配,缓冲294879字节并不奇怪。 在linux上,当您设置SO_SNDBUF时,内核只是将该值加倍

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


现在,使用的缓冲区不仅仅是用于您的数据,skb和内核需要的其他数据结构都分配在这些缓冲区中,这就是“管理开销”,这相当于多少开销取决于内核如何分割您提供的数据-因此,仅为从用户空间发送的数据保留256k的缓冲区空间是一项相当困难的任务,如果不是实际上不可能的任务。

谢谢,那么返回的长度是否不包含任何“管理开销”?只有数据本身?@hudac我相信它只是用户数据,尽管它肯定取决于您如何计算长度以及您在协议堆栈中的位置。还要注意的是,您可以在TCP套接字上执行SIOCOUTQ ioctl(),它应该为您提供TCP套接字缓冲区中的字节数(这将是尚未发送的数据量+已发送但对等方尚未确认的数据量)