我知道我可以使用该命令查看开放端口的列表lsof
。
我正在尝试查看按收听时间戳排序的结果。
该过程打开了多个 (~6) 个端口,我怀疑该端口上的初始化/绑定顺序是导致错误的原因。从技术上讲,应该可以通过查看在 Linux 系统上创建的 fd 文件的创建时间戳来找到绑定的相对时间戳。
我的问题是:是否有命令(netstat 或 lsof)可以做到这一点?
PS:我不想通过检查日志的路线,因为其中一些端口是由外部 jar 打开的,其初始化是我们无法控制的。
答案1
这些信息通常不会被记录。没有可用的文件“创建时间”,ctime
是文件 inode/元数据更改时间。因此,事后通常无法可靠地确定相对或绝对时间。
在我测试过的任何 Linux 系统(2.6.x 和 3.x)上,相关/proc
条目只有在您查看时才会实例化,所有时间戳都设置为首次查询目录的时间(即,这些是按需创建的,以显示当前状态,内核不会在每次文件句柄发生变化时不必要地更新这些)。别忘了这些都是符号链接,其时间戳与目标无关,并且这些套接字并不“存在于”文件系统中。
$ strace -tt -f -e trace=bind,listen /usr/bin/nc -l -p 8080
13:23:23.693432 bind(3, {sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr(
"0.0.0.0")},16) = 0
13:23:23.693542 listen(3, 1) = 0
几秒钟后,在另一个终端上:
$ date; ls -cl --full-time /proc/$(pgrep -f "^/usr/bin/nc -l -p 8080")/fd
Mon May 19 13:23:31 IST 2014
total 0
lrwx------ 1 mr users 64 2014-05-19 13:23:31.344141947 +0100 0 -> /dev/pts/206
lrwx------ 1 mr users 64 2014-05-19 13:23:31.344141947 +0100 1 -> /dev/pts/206
lrwx------ 1 mr users 64 2014-05-19 13:23:31.344141947 +0100 2 -> /dev/pts/206
lrwx------ 1 mr users 64 2014-05-19 13:23:31.344141947 +0100 3 -> socket:[206347913]
运行时,所有符号链接时间均设置为 8 秒后ls
。
请注意 的使用strace
,这可能是观察相关网络操作顺序的最简单方法(尽管性能略有下降)。-f
但您可能不需要或不想使用,它会跟踪所有生成的(子)进程,这可能会使输出混乱(如果是这样,则每个输出行都以其 PID 为前缀)。
下一个最简单的方法可能是使用auditd
/auditctl
规则(并仔细过滤!)来记录操作,但这也会对性能产生影响(如果您尚未运行auditd
,则系统范围strace
只会影响受监控的进程)。
当有对等方连接时,您可以使用netstat
查看连接详细信息(该-p
选项可能很有用,因为它将显示进程),或使用lsof
— 尽管两者都不会显示连接时间戳。要使用 记录这些连接strace
,请accept
在选项中添加系统调用列表trace=
,并添加一个-T
选项来计时每个系统调用: accept()
将(通常)阻止,仅显示调用的时间戳而不是完成时间。-T
这将允许您计算完成时间。
的额外输出accept()
如下所示:
13:25:46.022244 accept(3, {sa_family=AF_INET, sin_port=htons(57534), sin_addr=inet_addr(
"127.0.0.1")}, [16]) = 4 <3.167477>
显示套接字在 13:25:46 准备好接受连接,并在 3.167 秒后获得了第一个连接。
答案2
这似乎可以达到大部分效果:ls --full-time /proc/$PID/fd
您需要将该输出与来自的输出相结合lsof
才能知道哪个端口号对应哪个文件描述符。
更新:事实证明,返回的时间戳不是文件描述符的确切创建时间,而是ls
文件描述符创建后目录的第一个时间。因此,要使用上述方法获取正确的时间,您需要ls
在打开套接字时频繁运行该命令。