如何找到linux的套接字缓冲区大小

Posted

技术标签:

【中文标题】如何找到linux的套接字缓冲区大小【英文标题】:How to find the socket buffer size of linux 【发布时间】:2011-12-13 11:37:40 【问题描述】:

linux 的默认套接字缓冲区大小是多少?有什么命令可以查看吗?

【问题讨论】:

【参考方案1】:

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

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

然而,默认套接字缓冲区只是在初始化 sock 时设置,但内核会动态调整它们的大小(除非使用带有 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】:

在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

【讨论】:

改用socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) 是否安全?我在我的 Swift TCP 框架中使用这个 C 调用来获取缓冲区大小以减少 recv 调用。 注意:这也只是读缓冲区大小,使用SO_SNDBUF获取写缓冲区的大小。至少在linux下,你可以使用ioctl SIOCINQ和SIOCOUTQ,分别获取缓冲区的当前使用状态。【参考方案3】:

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

【讨论】:

“原子大小”是什么意思; sendfile() 和它有什么关系?您在哪里回答了有关默认套接字缓冲区大小的问题? @ EJP 原子大小 - 用于 4096b 套接字传输的 Linux 内部断言 - MT 安全、互斥体、1/16 内部管道。沙文件与它有很大关系。我想我有。默认缓冲区大小为 16*4096b。 这些都不能回答这个问题。它与套接字发送和接收缓冲区大小有关。与sendfile() 无关,因此与它无关,也不是原子传输大小,同上。【参考方案4】:

如果您想在终端中查看缓冲区大小,可以查看:

/proc/sys/net/ipv4/tcp_rmem(供阅读) /proc/sys/net/ipv4/tcp_wmem(写)

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

【讨论】:

还有/proc/sys/net/core/rmem_default 用于recv 和/proc/sys/net/core/wmem_default 用于发送,参考man7.org/linux/man-pages/man7/socket.7.html 我在man 7 tcpman 7 udp 中找到了更详细的描述。

以上是关于如何找到linux的套接字缓冲区大小的主要内容,如果未能解决你的问题,请参考以下文章

设置接受套接字的缓冲区大小

Linux UDP 接收缓冲区的最大大小

如何确定/设置套接字缓冲区大小?

如何在 Java 中为 Web 套接字客户端(Jetty)设置最大缓冲区大小

linux基础——内核参数

linux NFS共享存储