Linux 可以使用哪些值作为默认的 unix 套接字缓冲区大小?

sou*_*edi 8 linux unix-sockets

Linux 记录了 tcp 的默认缓冲区大小,但没有记录 AF_UNIX(“本地”)套接字的默认缓冲区大小。可以在运行时读取(或写入)该值。

cat /proc/sys/net/core/[rw]mem_default
Run Code Online (Sandbox Code Playgroud)

这个值是否总是在不同的 Linux 内核中设置相同,或者是否有一系列可能的值?

sou*_*edi 11

默认值不可配置,但在 32 位和 64 位 Linux 之间有所不同。写入的值似乎允许 256 个数据包,每个数据包 256 个字节,考虑到不同的每个数据包开销(具有 32 位与 64 位指针或整数的结构)。

在 64 位 Linux 4.14.18 上:212992 字节

在 32 位 Linux 4.4.92 上:163840 字节

读取和写入缓冲区的默认缓冲区大小相同。每个分组开销的组合struct sk_buffstruct skb_shared_info,所以它取决于这些结构(四舍五入为略对准)的精确尺寸。例如,在上面的 64 位内核中,每个数据包的开销是 576 字节。

http://elixir.free-electrons.com/linux/v4.5/source/net/core/sock.c#L265

/* Take into consideration the size of the struct sk_buff overhead in the
 * determination of these values, since that is non-constant across
 * platforms.  This makes socket queueing behavior and performance
 * not depend upon such differences.
 */
#define _SK_MEM_PACKETS     256
#define _SK_MEM_OVERHEAD    SKB_TRUESIZE(256)
#define SK_WMEM_MAX     (_SK_MEM_OVERHEAD * _SK_MEM_PACKETS)
#define SK_RMEM_MAX     (_SK_MEM_OVERHEAD * _SK_MEM_PACKETS)

/* Run time adjustable parameters. */
__u32 sysctl_wmem_max __read_mostly = SK_WMEM_MAX;
EXPORT_SYMBOL(sysctl_wmem_max);
__u32 sysctl_rmem_max __read_mostly = SK_RMEM_MAX;
EXPORT_SYMBOL(sysctl_rmem_max);
__u32 sysctl_wmem_default __read_mostly = SK_WMEM_MAX;
__u32 sysctl_rmem_default __read_mostly = SK_RMEM_MAX;
Run Code Online (Sandbox Code Playgroud)

有趣的是,如果您设置了非默认套接字缓冲区大小,Linux 会将其加倍以提供开销。这意味着,如果您发送较小的数据包(例如,小于上面的 576 字节),您将无法在缓冲区中容纳与您为其指定的大小一样多的用户数据字节。