Skip to content

Instantly share code, notes, and snippets.

@jiacai2050
Created June 11, 2023 12:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jiacai2050/cbbc7dd46397eaadd70ee512156e4b7c to your computer and use it in GitHub Desktop.
Save jiacai2050/cbbc7dd46397eaadd70ee512156e4b7c to your computer and use it in GitHub Desktop.
如何找出 TCP 连接建立时间与最后一次通讯时间

这个问题是在《形单影只的 Socket》最后留的问题,这里给出一个思路供大家参考,看下那篇文章再来看这个效果可能会更好。

传送门: 测试环境:Ubuntu 14.04 好了,进入正题。首先构造一个 TCP 连接,这里使用形单影只的 socket 来启动一个 echo server

$ nc -vp 11111 localhost 11111
Connection to localhost 11111 port [tcp/*] succeeded!

$ ss -ap | grep 11111
tcp    ESTAB      0      0            127.0.0.1:11111         127.0.0.1:11111    users:(("nc",15432,3))

可以看到 client 进程号是 15432,然后去 /proc/15432/net/tcp 文件里面搜索这个连接,需要注意的是这里面的 port 是用十六进制标示,所以需要转化下

$ printf "%x" 11111
2b67

$ grep 2B67 /proc/15432/net/tcp
   4: 0100007F:2B67 0100007F:2B67 01 00000000:00000000 00:00000000 00000000  1000        0 373609 1 0000000000000000 20 0 0 10 -1

找到 inode 列,在本次实验中是 373609。然后去 /proc/15432/fd 目录找到这个 inode 表示的文件

$ ls -Lli  | grep 373609
373609 srwxrwxrwx 1 vagrant      0 Jan  1  1970 3=
# 也可以不用 -i 选项
$ ls -l | grep 373609
lrwx------ 1 vagrant 64 Nov 12 12:03 3 -> socket:[373609]
# 这时会展示出 3 是指向 373609 这个 socket

找到 socket 对应的文件后,在用 stat 查看就好了

$ stat 3
  File: ‘3’ -> ‘socket:[373609]’
  Size: 64              Blocks: 0          IO Block: 1024   symbolic link
Device: 3h/3d   Inode: 373624      Links: 1
Access: (0700/lrwx------)  Uid: ( 1000/ vagrant)   Gid: ( 1000/ vagrant)
Access: 2018-11-12 12:03:56.288560896 +0800
Modify: 2018-11-12 12:03:43.706273046 +0800   # ls -l 默认显示 mtime
Change: 2018-11-12 12:03:43.706273046 +0800
 Birth: -

上面展示的信息表示的是 3 这个 symbolic link 文件的相关时间信息,由于这个文件只在该连接建立之初有修改,所以可以近似的看成该连接的创建时间,这就解决了第一个问题。

那么我们能不能通过 stat 'socket:[373609]' 取到该连接最后的通讯时间(即 modify time) 呢?

$ stat 'socket:[373609]'
stat: cannot stat ‘socket:[373609]’: No such file or directory

Boom!说没有这个文件!其实这里的 socket:[xxx] 并不是一个真实的文件,而是指向 /proc/net/tcp 里的一条记录而已,要想获取更多该连接信息,只能通过 ss netstat tcpdump 等命令,所以这里的结论是

无法获取一个连接上最后一个数据传输时间

参考

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment