简体   繁体   English

在python中是否有一种跨平台的方式来确定哪个进程正在侦听给定的端口?

[英]In python is there a cross-platform way of determining what process is listening to a given port?

In linux, I can use lsof -i as in the following function:在 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

Is there a cross-platform way to figure this out?有没有跨平台的方法来解决这个问题?

As a relevant reference, once I know the process id, the psutil library is very nice and lets me determine all sorts of useful process information for it in a cross-platform way.作为相关参考,一旦我知道进程 id, psutil库就非常好,它让我以跨平台的方式为其确定各种有用的进程信息。 I just can't get the first part to work (finding the pid) cross-platform at the moment.我目前无法让第一部分工作(找到 pid)跨平台。


If not familiar with the lsof -i switch, the output looks like below (after launching a python process that opens a TCP socket listening on port 1234):如果不熟悉lsof -i开关,输出如下所示(在启动 Python 进程打开 TCP 套接字侦听端口 1234 之后):

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

This answer is more of a tangent to your question, but if you can find OS-specific ways but nothing strictly portable, I'd make your module like the following这个答案更切合您的问题,但如果您能找到特定于操作系统的方法但没有严格的可移植性,我会让您的模块如下所示

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)

不,这不是python内置的。

Like Daenyth's anwer , this doesn't precisely answer the question you asked, but I think you'll probably find it helpful given that the answer to that seems to be "you can't".就像Daenyth 的回答一样,这并不能准确回答您提出的问题,但我认为您可能会发现它有帮助,因为答案似乎是“您不能”。

Well, NT's netstat.exe may not be quite as capable as that, but it can at least do this:好吧,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]

The "Can not obtain ownership information" lines are because I'm not running this as an administrator, so (just like on Linux) I can really only see this info for my own processes. “无法获取所有权信息”行是因为我不是以管理员身份运行它,所以(就像在 Linux 上一样)我真的只能看到我自己进程的这些信息。 (I'm probably actually allowed to do this for any process whose ACL grants me the necessary access, but in practice that means basically the same thing as "my processes" for non-admin users.) (我可能实际上被允许对其 ACL 授予我必要访问权限的任何进程执行此操作,但实际上这与非管理员用户的“我的进程”基本相同。)

The exact version of netstat.exe , as copied from Explorer's Properties dialog, is "5.1.2600.5512 (xpsp.080413-0852)".从资源管理器的“属性”对话框复制的netstat.exe的确切版本是“5.1.2600.5512 (xpsp.080413-0852)”。 I happen to be running XP SP3, but I'm not sure when this file was last updated.我碰巧运行的是 XP SP3,但我不确定这个文件是什么时候更新的。 (Yes, I am using a non-admin account in XP. It's not as easy as it should be, but it's also not as hard as you might think.) (是的,我在 XP 中使用的是非管理员帐户。这并不像应该的那么容易,但也没有您想象的那么难。)

The following code will help you retrieve the PID of a process running on a particular port.以下代码将帮助您检索在特定端口上运行的进程的 PID。 In this case it is 5556.在这种情况下,它是 5556。

import subprocess
import re

port = 5556
data = subprocess.check_output(['lsof', '-i:{}'.format(port)]).decode().split('\n')[1]
pid = re.match('^([a-zA-Z0-9]+)(\s+)([0-9]+)\s', data).groups()[2]
print(pid)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM