我知道 lsof 和 ss 提供有关连接的元数据。他们从哪里得到它?
例如,这表示一个连接:
ls -al /proc/102922/fd/98
lrwx------ 1 me me 64 dic 21 06:06 /proc/102922/fd/74 -> 'socket:[3803248]'
使用 ss 我可以看到更多信息:
tcp ESTAB 0 0 192.168.68.108:33966 198.252.206.25:https users:(("chrome",pid=102922,fd=98)) cubic wscale:9,7 rto:296 rtt:92.785/24.455 ato:40 mss:1448 pmtu:1500 rcvmss:536 advmss:1448 cwnd:10 bytes_sent:1463 bytes_acked:1464 bytes_received:336 segs_out:11 segs_in:7 data_segs_out:6 data_segs_in:2 send 1.25Mbps lastsnd:71284 lastrcv:71292 lastack:26068 pacing_rate 2.5Mbps delivery_rate 271kbps delivered:7 app_limited busy:308ms rcv_space:14480 rcv_ssthresh:64088 minrtt:86.996
但是,假设我的应用程序正在运行的系统由于某种原因没有 ss。如何从 socket:[3803248] 转到 ss 提供的 tcp 统计信息?我不打算完全重写 ss :) 但我很好奇文件系统中存在什么。
技巧:这样的事情通常可以通过运行
strace -o logfile.txt programname
;来解决。在您的情况下,您会发现它ss
创建了一个AF_NETLINK
套接字,并通过它发送和接收消息。Netlink是内核的逻辑接口,旨在提供对网络堆栈内部的访问。
使用
ldd $(which ss)
你会发现ss
似乎使用了libmnl库——这使得生成、发送、接收和解析这些消息变得可行。从理论上讲,您当然可以手工制作此类消息,但您只是在部分重新实现 libmnl(而且很可能更糟),所以您想使用它 - 它是由发明内核方面的同一个人所发明的,所以使用它有点道理。