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

问题描述 投票:0回答:5

如何使用 python 获取进程正在侦听的端口?进程的 pid 已知。

python linux sockets port
5个回答
34
投票

您可以使用psutil

>>> import psutil
>>> p = psutil.Process(2549)
>>> p.name()
'proftpd: (accepting connections)'
>>> p.net_connections()
[connection(fd=1, family=<AddressFamily.AF_PACKET: 10>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='::', port=21), raddr=(), status='LISTEN')]

...要过滤侦听套接字:

>>> [x for x in p.net_connections() if x.status == psutil.CONN_LISTEN]
[connection(fd=1, family=<AddressFamily.AF_PACKET: 10>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='::', port=21), raddr=(), status='LISTEN')]
>>>

25
投票

我的回答分为两部分:

1。获取shell中的信息

对于第一部分,

netstat
可以工作,但我更喜欢使用
lsof
,因为它可以用来提取信息更丰富、更简洁的列表。使用的确切选项可能会根据您的操作系统、内核和编译选项而有所不同,但我相信您想要这样的东西:

lsof -a -p23819 -i4

其中

23819
是您选择的 PID,
i4
表示所有 IPv4 套接字(尽管您可能需要
i6
用于 IPv6,视情况而定)。从那里,您可以通过 grep 管道来仅选择侦听套接字。

lsof -a -p23819 -i4 | grep LISTEN

(在

lsof
4.82 版本中,您还可以使用
-sTCP:LISTEN
标志而不是
grep
来选择侦听套接字,尽管此选项在 4.78 版本中似乎不可用)

2。从 Python 调用

lsof

您应该能够使用

lsof
模块调用
subprocess
并从 Python 读取输出,如下所示:

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]

希望这有帮助!


4
投票

如果您不想解析像 netstat 或 lsof 这样的程序的输出,您可以仔细研究 /proc 文件系统并尝试查找有关其中文件的文档。

/proc/<pid>/net/tcp
您可能特别感兴趣。 当然,这些文件的格式可能会在内核版本之间发生变化,因此解析命令输出通常被认为更可靠。


1
投票

您可以使用

netstat -lnp
,最后一列将包含pid和进程名称。在 Python 中,您可以解析此命令的输出。


0
投票

还有一件事没有提到。 Python 中的大多数端口应用程序都采用命令行参数。您可以解析/proc/pid/cmdline并解析出端口号。这避免了在具有大量连接的服务器上使用 ss 或 netstat 的巨大开销。

© www.soinside.com 2019 - 2024. All rights reserved.