开发者

How to obtain ports that a process in listening on?

How do I get the ports that a process is listening on using 开发者_运维百科python? The pid of the process is known.


You can use 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')]

...To filter for listening sockets:

>>> [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')]
>>>


There are two parts to my answer:

1. Getting the information in the shell

For the first part, netstat would work, but I prefer using lsof, since it can be used to extract a more informative and concise list. The exact options to use may vary based on your OS, kernel and compilation options, but I believe you want something like this:

lsof -a -p23819 -i4

Where 23819 is the PID you are selecting for, and i4 denotes all IPv4 sockets (though you might want i6 for IPv6, as the case may be). From there, you can pipe through grep to select only listening sockets.

lsof -a -p23819 -i4 | grep LISTEN

(In lsof version 4.82, you can additionally use the -sTCP:LISTEN flag instead of grep to select listening sockets, though this option doesn't seem to be available back in version 4.78)

2. Calling lsof from Python

You should be able to call lsof and read the output, from Python, using the subprocess module, like so:

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]

Hope this helps!


If you don't want to parse the output of a program like netstat or lsof, you can grovel through the /proc filesystem and try to find documentation on the files within. /proc/<pid>/net/tcp might be especially interesting to you. Of course, the format of those files might change between kernel releases, so parsing command output is generally considered more reliable.


You can use netstat -lnp, last column will contain pid and process name. In Python you can parse output of this command.


One thing that wasn't mentioned. Most port applications in python take a command line argument. You can parse /proc/pid/cmdline and parse out the port number. This avoids the large overhead of using ss or netstat on servers with a ton of connections.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜