我正在开发一个连接到实时数据服务器(使用 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_queued
和sk_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_queue
sk_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)