内核套接字结构和 TCP_DIAG

内核套接字结构和 TCP_DIAG

我正在开发一个连接到实时数据服务器(使用 TCP)的软件,但我有一些连接丢失。我的猜测是客户端读取来自服务器的数据的速度不够快。因此我想监控我的 TCP 套接字。为此我找到了“ss”工具。

该工具允许查看每个套接字的状态 - 这是命令输出的示例行ss -inm 'src *:50000'

ESTAB      0      0             184.7.60.2:50000       184.92.35.104:1105
  mem:(r0,w0,f0,t0) sack rto:204 rtt:1.875/0.75 ato:40

我的问题是:内存部分是什么意思?查看该工具的源代码,我发现数据来自内核结构(sock在 中sock.h)。更准确地说,它来自以下领域:

r = sk->sk_rmem_alloc
w = sk->sk_wmem_queued;
f = sk->sk_forward_alloc;
t = sk->sk_wmem_alloc;

有人知道他们的意思吗?我的猜测是:

  • rmem_alloc:入站缓冲区的大小
  • wmem_alloc:出站缓冲区的大小
  • sk_forward_alloc: ???
  • sk->sk_wmem_queued: ???

这是我的缓冲区大小:

net.ipv4.tcp_rmem = 4096        87380   174760
net.ipv4.tcp_wmem = 4096        16384   131072
net.ipv4.tcp_mem = 786432       1048576 1572864
net.core.rmem_default = 110592
net.core.wmem_default = 110592
net.core.rmem_max = 1048576
net.core.wmem_max = 131071

答案1

sk_forward_alloc是向前分配的内存,即套接字配额中当前可用的总内存。

sk_wmem_queued是在传输队列中排队并且尚未发送或尚未确认的套接字发送缓冲区使用的内存量。

您可以在第 9 章中了解有关 TCP 内存管理的更多信息Linux 中的 TCP/IP 体系结构、设计和实现 作者:Sameer Seth、M. Ajaykumar Venkatesulu

答案2

关于sk_wmem_queuedsk_wmem_alloc,我问了同样的问题所以我将在这里复制答案:

我给 Linux 网络堆栈的贡献者 Eric Dumazet 发了一封电子邮件,答案如下:

sk_wmem_alloc跟踪 skb 排队的字节数传输堆栈:qdisc 层和 NIC TX 环形缓冲区。

如果 TCP 写入队列中有 1 MB 数据尚未发送(cwnd 限制),sk_wmem_queue则约为 1 MB,但sk_wmem_alloc约为 0

用于理解这三种类型的队列(套接字缓冲区、qdisc 队列和设备队列)的一个非常好的文档是这篇文章(相当长)。简而言之,套接字首先将数据包直接推送到 qdisc 队列,然后将它们转发到设备队列。当 qdisc 队列已满时,套接字开始在自己的写入队列中缓冲数据。

网络堆栈将数据包直接放入排队规则中,或者如果队列已满,则将数据包推回到上层(例如套接字缓冲区)

所以基本上:是套接字缓冲区 ( )sk_wmem_queues使用的内存,而是 qdisc 和设备队列中的数据包使用的内存。sock.sk_write_queuesk_wmem_alloc

答案3

请参阅 ss 的手册页。

<fwd_alloc>
   The  memory allocated by the socket as cache, but not used for receiving/sending packet yet. If need memory to send/receive packet, the memory in this cache will be used before allocate additional memory.

<wmem_queued>
   The memory allocated for sending packet (which has not been sent to layer 3)

相关内容