在Python中,是否有跨平台的方法确定哪个进程在监听特定端口?

2 投票
4 回答
2293 浏览
提问于 2025-04-16 05:05

在Linux系统中,我可以使用 lsof -i 命令,像下面这个功能一样:

def FindProcessUsingPort(portnum):
    import os
    fp = os.popen("lsof -i :%s" % portnum)
    lines = fp.readlines()
    fp.close()
    pid = None
    if len(lines) >= 2:
        pid = int(lines[1].split()[1])
    return pid

有没有一种跨平台的方法可以做到这一点呢?

作为相关参考,一旦我知道了进程的ID,psutil 这个库非常好用,可以让我以跨平台的方式获取各种有用的进程信息。 但我现在就是找不到第一步(获取进程ID)在不同平台上怎么做。


如果你不熟悉 lsof -i 这个命令,它的输出结果大概是这样的(在启动一个打开TCP套接字并监听1234端口的Python进程后):

$ lsof -i :1234
COMMAND   PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
python  22380 russ   15u  IPv4 4015476      0t0  TCP *:1234 (LISTEN)

4 个回答

2

就像Daenyth的回答那样,这个内容并没有直接回答你问的问题,但我觉得你可能会觉得它有用,因为那个问题的答案似乎是“你不能做到”。

好吧,NT的netstat.exe可能没有那么强大,但至少可以做到这一点:

C:\Documents and Settings\Sam\My Documents>netstat -o -b -n

Active Connections

  Proto  Local Address          Foreign Address        State           PID
  TCP    127.0.0.1:1083         127.0.0.1:6000         ESTABLISHED     3716
  [Xming.exe]

  TCP    127.0.0.1:1084         127.0.0.1:6000         ESTABLISHED     3716
  [Xming.exe]

  TCP    127.0.0.1:1085         127.0.0.1:6000         ESTABLISHED     3716
  [Xming.exe]

  TCP    127.0.0.1:1214         127.0.0.1:9481         ESTABLISHED     236
  Can not obtain ownership information
  TCP    127.0.0.1:1231         127.0.0.1:31416        ESTABLISHED     2764
  [boincmgr.exe]

  TCP    127.0.0.1:3814         127.0.0.1:6000         ESTABLISHED     716
  [putty.exe]

那些“无法获取所有权信息”的提示是因为我没有以管理员身份运行这个程序,所以(就像在Linux上一样)我只能看到自己进程的信息。(实际上,我可能可以查看任何我有权限的进程的信息,但对于非管理员用户来说,这基本上和“我的进程”是一样的。)

从资源管理器的属性对话框中复制的netstat.exe的确切版本是“5.1.2600.5512 (xpsp.080413-0852)”。我正好在使用XP SP3,但不确定这个文件最后一次更新是什么时候。(是的,我在XP中使用的是非管理员账户。这并没有想象中那么简单,但也没有那么难。)

2

这个回答跟你的问题有点偏离,不过如果你能找到一些特定操作系统的方法,但没有完全通用的解决方案,我建议你可以像下面这样来设计你的模块。

def find_port_owner_windows(p):
    doit()

def find_port_owner_linux(p):
    doit2()

port_finders = {'nt': find_port_owner_windows,
                'posix': find_port_owner_linux}

try:
    find_port_owner = port_finders[os.name]
except KeyError:
    raise RuntimeError("No known port finder for your OS (%s)" % os.name)
2

不,这个功能在Python里是没有的。

撰写回答