ss 命令中的Recv-Q与Send-Q

1. 前言 【ss 命令中的Recv-Q与Send-Q】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

    推荐阅读