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套接字缓冲区中的字节数(这将是尚未发送的数据量+已发送但对等方尚未确认的数据量)