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

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

【问题讨论】:

    标签: linux sockets buffer


    【解决方案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(写)

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

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多