美文网首页
TCP协议中的backlog参数

TCP协议中的backlog参数

作者: cp3_1dbc | 来源:发表于2018-05-10 10:56 被阅读0次

    backlog参数的含义

    TCP建立连接是要进行三次握手,但是否完成三次握手后,服务器就处理(accept)呢?

    backlog其实是一个连接队列,在Linux内核2.2之前,backlog大小包括半连接状态全连接状态两种队列大小。

    • 半连接状态为:服务器处于Listen状态时收到客户端SYN报文时放入半连接队列中,即SYN queue(服务器端口状态为:SYN_RCVD)。
    • 全连接状态为:TCP的连接状态从服务器(SYN+ACK)响应客户端后,到客户端的ACK报文到达服务器之前,则一直保留在半连接状态中;当服务器接收到客户端的ACK报文后,该条目将从半连接队列搬到全连接队列尾部,即 accept queue (服务器端口状态为:ESTABLISHED)。

    在Linux内核2.2之后,分离为两个backlog来分别限制半连接(SYN_RCVD状态)队列大小和全连接(ESTABLISHED状态)队列大小。

    • SYN queue 队列长度由 /proc/sys/net/ipv4/tcp_max_syn_backlog 指定,默认为2048。
    • Accept queue 队列长度由 /proc/sys/net/core/somaxconn 和使用listen函数时传入的参数,二者取最小值。默认为128。在Linux内核2.4.25之前,是写死在代码常量 SOMAXCONN ,在Linux内核2.4.25之后,在配置文件 /proc/sys/net/core/somaxconn 中直接修改,或者在 /etc/sysctl.conf 中配置 net.core.somaxconn = 128 。

    两个队列在连接过程中所处的位置如下图所示:

    tcp_backlog.png

    如何查看监听状态

    chris@chris-VirtualBox:/media/sf_share/myspace$ netstat -l
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State      
    tcp        0      0 *:5555                  *:*                     LISTEN     
    tcp        0      0 chris-VirtualBox:domain *:*                     LISTEN     
    tcp        0      0 localhost:ipp           *:*                     LISTEN     
    tcp6       0      0 ip6-localhost:ipp       [::]:*                  LISTEN     
    udp        0      0 *:mdns                  *:*                                
    udp        0      0 *:42226                 *:*                                
    udp        0      0 *:57698                 *:*                                
    udp        0      0 *:ipp                   *:*                                
    udp        0      0 chris-VirtualBox:domain *:*                                
    udp        0      0 *:bootpc                *:*                                
    udp6       0      0 [::]:mdns               [::]:*                             
    udp6       0      0 [::]:38317              [::]:*                             
    raw6       0      0 [::]:ipv6-icmp          [::]:*     
    

    Recv-Q & Send-Q

    先看下man netstat中的说明:

    • Recv-Q:The count of bytes not copied by the user program connected to this socket.
    • Send-Q:The count of bytes not acknowledged by the remote host.

    这里有一篇关于这两个队列的分析文章,https://www.cnblogs.com/leezhxing/p/5329786.html,结论是这样,要区分LISTEN状态和其他状态:

    • LISTEN 状态: Recv-Q 表示的当前等待服务端调用 accept 完成三次握手的 listen backlog 数值,也就是说,当客户端通过 connect() 去连接正在 listen() 的服务端时,这些连接会一直处于这个 queue 里面直到被服务端 accept();Send-Q 表示的则是最大的 listen backlog 数值,这就就是上面提到的 min(backlog, somaxconn) 的值。
    • 其余状态: 非 LISTEN 状态之前理解的没有问题。Recv-Q 表示 receive queue 中的 bytes 数量;Send-Q 表示 send queue 中的 bytes 数值。

    在我的机器上做了下验证

    • 操作系统
    $ uname -a
    Linux ubuntu 3.11.0-15-generic #25~precise1-Ubuntu SMP Thu Jan 30 17:39:31 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
    

    在8888这个端口启动一个监听程序, 程序中不accept

    • netstat命令查看
    $ netstat -apn |grep 8888
    tcp        0      0 127.0.0.1:8888          0.0.0.0:*               LISTEN      5399/thundering_her
    
    • 打开两个telnet连接
    telnet 127.0.0.1 8888
    
    • ss命令查看
    $ ss -l |grep 8888
    LISTEN      2      50                                       127.0.0.1:8888                                              *:* 
    

    Send-Q为2,Recv-Q为listen中设置的值

    结论:
    两个命令中Send-Q和Recv-Q的含义是不同的,

    • netstat中应该是man里面说明的含义
    • ss中才是上面文章中的结论:
      1. Recv-Q 表示的当前等待服务端调用 accept 完成三次握手的 listen backlog 数值;
      2. Send-Q 表示min(backlog, somaxconn)

    相关文章

      网友评论

          本文标题:TCP协议中的backlog参数

          本文链接:https://www.haomeiwen.com/subject/tssarftx.html