如何获取一个进程正在监听的端口?

23 投票
5 回答
25058 浏览
提问于 2025-04-15 23:38

我想知道怎么用Python获取一个进程正在监听的端口,而这个进程的ID我已经知道了。

5 个回答

4

如果你不想去分析像 netstat 或 lsof 这样的程序输出,你可以直接查看 /proc 文件系统,试着找到里面文件的说明。/proc/<pid>/net/tcp 这个路径可能会特别有意思。不过,要注意的是,这些文件的格式可能会在不同的内核版本中发生变化,所以一般来说,分析命令的输出会更可靠一些。

25

我的回答分为两个部分:

1. 在命令行获取信息

对于第一部分,netstat可以用,但我更喜欢用lsof,因为它能提供更详细和简洁的列表。具体使用的选项可能会根据你的操作系统、内核和编译选项有所不同,但我觉得你可以试试这样的命令:

lsof -a -p23819 -i4

这里的23819是你要选择的进程ID,i4表示所有的IPv4连接(如果需要IPv6的话,可以用i6)。接下来,你可以用grep来筛选出正在监听的连接。

lsof -a -p23819 -i4 | grep LISTEN

(在lsof的4.82版本中,你还可以使用-sTCP:LISTEN这个选项来直接选择监听的连接,不过在4.78版本中似乎没有这个选项)

2. 从Python调用lsof

你可以通过Python中的subprocess模块来调用lsof并读取输出,像这样:

from subprocess import Popen, PIPE
p1 = Popen(['lsof', '-a', '-p23819', '-i4'], stdout=PIPE)
p2 = Popen(["grep", "LISTEN"], stdin=p1.stdout, stdout=PIPE)
output = p2.communicate()[0]

希望这对你有帮助!

34

你可以使用 psutil 这个库:

>>> import psutil
>>> p = psutil.Process(2549)
>>> p.name()
'proftpd: (accepting connections)'
>>> p.connections()
[connection(fd=1, family=10, type=1, local_address=('::', 21), remote_address=(), status='LISTEN')]

...来筛选出正在监听的套接字:

>>> [x for x in p.get_connections() if x.status == psutil.CONN_LISTEN]
[connection(fd=1, family=10, type=1, local_address=('::', 21), remote_address=(), status='LISTEN')]
>>>

撰写回答