关于网络:ss-命令中的RecvQ与SendQ

38次阅读

共计 821 个字符,预计需要花费 3 分钟才能阅读完成。

1. 前言

ss 是日常应用的网络工具之一,然而工作中发现对其 Recv-Q, Send-Q 了解存在误差,故整顿材料,造成此博客

2. 论断

<1> 当 socket 是 listen 状态 (eg: ss -lnt)
    Recv-Q: 全连贯队列的大小,也就是以后已实现三次握手并期待服务端 accept() 的 TCP 连贯
    Send-Q: 全连贯最大队列长度
<2> 当 socket 是非 listen 状态 (eg: ss -nt)
    Recv-Q: 未被利用过程读取的字节数;Send-Q: 已发送但未收到确认的字节数;

3. 源码剖析

参看 tcp_diag_get_info

static void tcp_diag_get_info(struct sock *sk, struct inet_diag_msg *r,
                  void *_info)
{
    struct tcp_info *info = _info;

    // listen 状态
    if (inet_sk_state_load(sk) == TCP_LISTEN) {
        // recv-q 是 accept 队列以后大小
        r->idiag_rqueue = sk->sk_ack_backlog;
        // send-q 是 accept 队列最大大小
        r->idiag_wqueue = sk->sk_max_ack_backlog;

    // 非 Listen 状态
    } else if (sk->sk_type == SOCK_STREAM) {const struct tcp_sock *tp = tcp_sk(sk);
        // recv-q = 收到 - 读取(未读取字节数)r->idiag_rqueue = max_t(int, READ_ONCE(tp->rcv_nxt) -
                         READ_ONCE(tp->copied_seq), 0);
        // send-q = 发送 - 被确认发送 = (未确认的发送数)
        r->idiag_wqueue = READ_ONCE(tp->write_seq) - tp->snd_una;
    }
    if (info)
        tcp_get_info(sk, info);
}

4. 试验验证

todo

正文完
 0