如何查找Linux的套接字缓冲区大小

84

Linux的默认套接字缓冲区大小是多少? 有没有命令可以查看它?

5个回答

133

如果你想在终端中查看缓冲区大小,可以查看以下内容:

  • /proc/sys/net/ipv4/tcp_rmem(用于读取)
  • /proc/sys/net/ipv4/tcp_wmem(用于写入)

它们包含三个数字,分别是最小值、默认值和最大内存大小值(以字节为单位)。


25
иҝҳжңү/proc/sys/net/core/rmem_defaultз”ЁдәҺжҺҘ收ж“ҚдҪңпјҢд»ҘеҸҠ/proc/sys/net/core/wmem_defaultз”ЁдәҺеҸ‘йҖҒж“ҚдҪңпјҢеҸӮиҖғй“ҫжҺҘпјҡhttp://man7.org/linux/man-pages/man7/socket.7.htmlгҖӮ - Okkenator
3
我在 man 7 tcpman 7 udp 中找到了更详细的描述。 - Vladimír Čunát
请查看@VladimírČunát,并查看man 7 socket,并搜索proc interfaces - Gabriel Staples

43

要在C/C++程序中获取缓冲区大小,可以按以下步骤进行

int n;
unsigned int m = sizeof(n);
int fdsocket;
fdsocket = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); // example
getsockopt(fdsocket,SOL_SOCKET,SO_RCVBUF,(void *)&n, &m);
// now the variable n will have the socket size

1
调用 socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) 是否安全?我在我的 Swift TCP 框架中使用这个 C 调用来获取缓冲区大小以减少 recv 调用。 - DevAndArtist
2
注意:这仅是读缓冲区的大小,请使用SO_SNDBUF获取写缓冲区的大小。在至少Linux下,您可以使用ioctl SIOCINQ和SIOCOUTQ来分别获取缓冲区的当前使用状态。 - Rahly

26

正如已经指出的那样,可以在/proc中查看当前默认套接字缓冲区大小,也可以使用sysctl检查它们(注意:虽然名称包含ipv4,但这些大小也适用于ipv6套接字 - ipv6 tcp_v6_init_sock()代码只是调用ipv4 tcp_init_sock()函数):

 sysctl net.ipv4.tcp_rmem
 sysctl net.ipv4.tcp_wmem

然而,默认套接字缓冲区在套接字初始化时仅设置,但内核会根据需要动态调整它们的大小(除非使用带有SO_SNDBUF的setsockopt()设置)。当前打开套接字的实际缓冲区大小可以使用ss命令(iproute/iproute2软件包的一部分)进行检查,该命令还可以提供有关套接字的拥塞控制参数等其他信息。例如,要列出当前打开的TCP(t选项)套接字和相关的内存(m)信息:
ss -tm

以下是一些示例输出:
State       Recv-Q Send-Q        Local Address:Port        Peer Address:Port
ESTAB       0      0             192.168.56.102:ssh        192.168.56.1:56328
skmem:(r0,rb369280,t0,tb87040,f0,w0,o0,bl0,d0)

以下是关于skmem(套接字内存)的简要解释 - 如果需要更多信息,请查看内核源代码(即sock.h):
r:sk_rmem_alloc
rb:sk_rcvbuf          # current receive buffer size
t:sk_wmem_alloc
tb:sk_sndbuf          # current transmit buffer size
f:sk_forward_alloc
w:sk_wmem_queued      # persistent transmit queue size
o:sk_omem_alloc
bl:sk_backlog
d:sk_drops

2

我仍在努力整理细节,但是除了已经给出的答案之外,以下是一些重要的命令:

cat /proc/sys/net/ipv4/udp_mem
cat /proc/sys/net/core/rmem_max
cat /proc/sys/net/ipv4/tcp_rmem
cat /proc/sys/net/ipv4/tcp_wmem
ss -m  # see `man ss`

参考资料和帮助页面:

  1. Man pages
    man 7 socket
    man 7 udp
    man 7 tcp
    man ss
    
  2. https://www.linux.org/threads/how-to-calculate-tcp-socket-memory-usage.32059/

-6

原子大小为4096字节,最大大小为65536字节。Sendfile使用16个管道,每个管道的大小为4096字节。 命令:ioctl(fd,FIONREAD,&buff_size)。


6
"原文:What does 'atomic size' mean; what does sendfile() have to do with it; and where have you answered the question about the default socket buffer size?"请问什么是“原子大小”?sendfile() 与此有什么关系?你在哪里回答了关于默认套接字缓冲区大小的问题? - user207421
@EJP原子大小 - Linux内部针对4096b套接字传输的断言 - MT安全,互斥锁,1/16内部管道。sandfile与此有很大关系。我认为我已经解决了。默认缓冲区大小为16 * 4096b。 - Dawid Szymański
1
这些都不是问题的答案。它涉及套接字发送和接收缓冲区大小,而与sendfile()无关,因此与之毫无关系,原子传输大小也是如此。 - user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接