使用Python识别监听端口

发布于 2024-12-05 08:33:19 字数 293 浏览 0 评论 0原文

在从 bash 翻译一些脚本时,我遇到了许多使用 netstat -an 来查找我们的服务之一是否正在侦听的情况。虽然我知道我可以只使用 subprocess.call 或其他甚至 popen 我宁愿使用 pythonic 解决方案,所以我没有利用我们正在运行的 unix 环境。

从我读到的内容来看,套接字模块应该有一些东西,但我还没有看到任何检查侦听端口的内容。可能是我不理解一个简单的技巧,但到目前为止我知道如何连接到套接字,并编写一些东西让我知道连接何时失败。但我不一定找到了专门检查端口以查看其是否正在监听的东西。

有什么想法吗?

In translating some scripts from bash, I am encountering many uses of netstat -an to find if one of our services is listening. While I know I can just use subprocess.call or other even popen I would rather use a pythonic solution so I am not leveraging the unix environment we are operating in.

From what I have read the socket module should have something but I haven't seen anything that checks for listening ports. It could be me not understanding a simple trick, but so far I know how to connect to a socket, and write something that lets me know when that connection failed. But not necessarily have I found something that specifically checks the port to see if its listening.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

我不是你的备胎 2024-12-12 08:33:19

尝试连接怎么样...

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = s.connect_ex(('127.0.0.1', 3306))

if result == 0:
    print('socket is open')
s.close()

How about trying to connect...

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = s.connect_ex(('127.0.0.1', 3306))

if result == 0:
    print('socket is open')
s.close()
身边 2024-12-12 08:33:19

我知道这个问题很旧,但我是为初学者写的。如果您想识别系统上的侦听端口,可以使用下面的代码。

from socket import *

Port = 0 #First port.
while Port <= 65535: #Port 65535 is last port you can access.
    try:
        try:
            Socket = socket(AF_INET, SOCK_STREAM, 0) #Create a socket.
        except:
            print("Error: Can't open socket!\n")    
            break #If can't open socket, exit the loop.
        Socket.connect(("127.0.0.1", Port)) #Try connect the port. If port is not listening, throws ConnectionRefusedError. 
        Connected = True
    except ConnectionRefusedError:
        Connected = False       
    finally:
        if(Connected and Port != Socket.getsockname()[1]): #If connected,
            print("{}:{} Open \n".format("127.0.0.1", Port)) #print port.
        Port = Port + 1 #Increase port.
        Socket.close() #Close socket.

I know this question is old, but I write this for beginners. If you want to identify listening ports on your system, you can use the code below.

from socket import *

Port = 0 #First port.
while Port <= 65535: #Port 65535 is last port you can access.
    try:
        try:
            Socket = socket(AF_INET, SOCK_STREAM, 0) #Create a socket.
        except:
            print("Error: Can't open socket!\n")    
            break #If can't open socket, exit the loop.
        Socket.connect(("127.0.0.1", Port)) #Try connect the port. If port is not listening, throws ConnectionRefusedError. 
        Connected = True
    except ConnectionRefusedError:
        Connected = False       
    finally:
        if(Connected and Port != Socket.getsockname()[1]): #If connected,
            print("{}:{} Open \n".format("127.0.0.1", Port)) #print port.
        Port = Port + 1 #Increase port.
        Socket.close() #Close socket.
凡间太子 2024-12-12 08:33:19

在 Linux 上,我们可以使用 strace 来查看 netstat -ln 正在读取并
解析 /proc 文件系统中的各种值。

$ strace netstat -ln 2>&1| grep '/proc'
open("/proc/net/tcp", O_RDONLY)         = 3
open("/proc/net/tcp6", O_RDONLY)        = 3
open("/proc/net/udp", O_RDONLY)         = 3
open("/proc/net/udp6", O_RDONLY)        = 3
open("/proc/net/raw", O_RDONLY)         = 3
open("/proc/net/raw6", O_RDONLY)        = 3
open("/proc/net/unix", O_RDONLY)        = 3
open("/proc/net/ipx/socket", O_RDONLY)  = -1 ENOENT (No such file or directory)
open("/proc/net/ipx", O_RDONLY)         = -1 ENOENT (No such file or directory)
open("/proc/net/ax25", O_RDONLY)        = -1 ENOENT (No such file or directory)
open("/proc/net/x25", O_RDONLY)         = -1 ENOENT (No such file or directory)
open("/proc/net/x25", O_RDONLY)         = -1 ENOENT (No such file or directory)
open("/proc/net/nr", O_RDONLY)          = -1 ENOENT (No such file or directory)

所以你可以从Python读取这些文件并提取你想要的数据
需要。

$ cat /proc/net/tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
   0: 00000000:0050 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 8190 1 00000000 300 0 0 2 -1
   1: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 6458 1 00000000 300 0 0 2 -1
   2: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 10425 1 00000000 300 0 0 2 -1
   3: 8D0BA8C0:8801 689255D1:01BB 01 00000000:00000000 00:00000000 00000000  1000        0 1680975 1 00000000 24 4 16 6 -1
   4: 8D0BA8C0:D142 97E67D4A:01BB 06 00000000:00000000 03:000012E8 00000000     0        0 0 3 00000000
   5: 8D0BA8C0:D1A1 96E67D4A:01BB 01 00000000:00000000 00:00000000 00000000  1000        0 1672130 1 00000000 24 4 18 5 -1
   6: 8D0BA8C0:D148 97E67D4A:01BB 01 00000000:00000000 00:00000000 00000000  1000        0 1679875 1 00000000 24 4 20 5 -1

侦听套接字将具有远程地址 00000000:0000

地址:端口对为十六进制。看:
* 我如何匹配每个/proc/net/tcp 条目到每个打开的套接字?

您可以与 /proc//fd 交叉引用。例如,sshd 是
在我的笔记本电脑上运行。

$ cat /var/run/sshd.pid
522

$ sudo ls -l /proc/522/fd
total 0
lrwx------ 1 root root 64 2011-09-15 21:32 0 -> /dev/null
lrwx------ 1 root root 64 2011-09-15 21:32 1 -> /dev/null
lrwx------ 1 root root 64 2011-09-15 21:32 2 -> /dev/null
lrwx------ 1 root root 64 2011-09-15 21:32 3 -> socket:[6456]
lrwx------ 1 root root 64 2011-09-15 21:32 4 -> socket:[6458]

套接字 6456 对应于第二行列出的 inode 6458
/proc/net/tcp.conf

所以你可以从proc中获取所有这些信息,但你最终可能会
重新发明 netstat -lntp

On Linux we can use strace to see that netstat -ln is reading and
parsing various values from the /proc filesystem.

$ strace netstat -ln 2>&1| grep '/proc'
open("/proc/net/tcp", O_RDONLY)         = 3
open("/proc/net/tcp6", O_RDONLY)        = 3
open("/proc/net/udp", O_RDONLY)         = 3
open("/proc/net/udp6", O_RDONLY)        = 3
open("/proc/net/raw", O_RDONLY)         = 3
open("/proc/net/raw6", O_RDONLY)        = 3
open("/proc/net/unix", O_RDONLY)        = 3
open("/proc/net/ipx/socket", O_RDONLY)  = -1 ENOENT (No such file or directory)
open("/proc/net/ipx", O_RDONLY)         = -1 ENOENT (No such file or directory)
open("/proc/net/ax25", O_RDONLY)        = -1 ENOENT (No such file or directory)
open("/proc/net/x25", O_RDONLY)         = -1 ENOENT (No such file or directory)
open("/proc/net/x25", O_RDONLY)         = -1 ENOENT (No such file or directory)
open("/proc/net/nr", O_RDONLY)          = -1 ENOENT (No such file or directory)

So you can just read those files from Python and extract the data you
need.

$ cat /proc/net/tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
   0: 00000000:0050 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 8190 1 00000000 300 0 0 2 -1
   1: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 6458 1 00000000 300 0 0 2 -1
   2: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 10425 1 00000000 300 0 0 2 -1
   3: 8D0BA8C0:8801 689255D1:01BB 01 00000000:00000000 00:00000000 00000000  1000        0 1680975 1 00000000 24 4 16 6 -1
   4: 8D0BA8C0:D142 97E67D4A:01BB 06 00000000:00000000 03:000012E8 00000000     0        0 0 3 00000000
   5: 8D0BA8C0:D1A1 96E67D4A:01BB 01 00000000:00000000 00:00000000 00000000  1000        0 1672130 1 00000000 24 4 18 5 -1
   6: 8D0BA8C0:D148 97E67D4A:01BB 01 00000000:00000000 00:00000000 00000000  1000        0 1679875 1 00000000 24 4 20 5 -1

The listening sockets will have remote address 00000000:0000

The address:port pairs are in hex. See:
* How can i match each /proc/net/tcp entry to each opened socket?

You could cross reference with /proc//fd. For example, sshd is
running on my laptop.

$ cat /var/run/sshd.pid
522

$ sudo ls -l /proc/522/fd
total 0
lrwx------ 1 root root 64 2011-09-15 21:32 0 -> /dev/null
lrwx------ 1 root root 64 2011-09-15 21:32 1 -> /dev/null
lrwx------ 1 root root 64 2011-09-15 21:32 2 -> /dev/null
lrwx------ 1 root root 64 2011-09-15 21:32 3 -> socket:[6456]
lrwx------ 1 root root 64 2011-09-15 21:32 4 -> socket:[6458]

Socket 6456 corresponds to inode 6458 listed in the second row of
/proc/net/tcp.

So you can get all this information from proc, but you may end up
reinventing netstat -lntp

半衾梦 2024-12-12 08:33:19
import psutil
connections = psutil.net_connections()

参考:
https://stackoverflow.com/a/6244270

import psutil
connections = psutil.net_connections()

Reference:
https://stackoverflow.com/a/6244270

懒的傷心 2024-12-12 08:33:19

您可以尝试连接到有问题的端口,或模拟 netstat

执行后者将是特定于操作系统的。在 Linux 上,您可以检查 /proc/net/tcp。它看起来像这样:

  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode                                                     
   0: 00000000:C809 00000000:0000 0A 00000000:00000000 00:00000000 00000000   117        0 8381 1 ffff8802f22a8000 300 0 0 2 -1                      
   1: 00000000:16CC 00000000:0000 0A 00000000:00000000 00:00000000 00000000  1026        0 14336 1 ffff8802f2249440 300 0 0 2 -1                     
   2: 00000000:006F 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 7876 1 ffff8802f2248000 300 0 0 2 -1                      
   3: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 8163 1 ffff8802f3578000 300 0 0 2 -1                      
   4: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 981582 1 ffff8800d7a53600 300 0 0 2 -1                    
   5: 00000000:0019 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 9129 1 ffff8802edc886c0 300 0 0 2 -1                      
   6: 00000000:021A 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 9016 1 ffff8802edc88000 300 0 0 2 -1                      
   7: 00000000:2B1C 00000000:0000 0A 00000000:00000000 00:00000000 00000000  1026        0 783709 1 ffff8803119cca40 300 0 0 2 -1                    
   8: 00000000:977C 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 24292 1 ffff8802f224e540 300 0 0 2 -1                     

您正在查找 st(“状态”)列中包含 0A 的行。 local_address 中冒号后面的数字 - C80916CC 等 - 是有侦听进程的 TCP 端口号(十六进制) 。

You could either try connecting to the port in question, or emulate netstat.

Doing the latter will be OS-specific. On Linux you can examine /proc/net/tcp. It looks like this:

  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode                                                     
   0: 00000000:C809 00000000:0000 0A 00000000:00000000 00:00000000 00000000   117        0 8381 1 ffff8802f22a8000 300 0 0 2 -1                      
   1: 00000000:16CC 00000000:0000 0A 00000000:00000000 00:00000000 00000000  1026        0 14336 1 ffff8802f2249440 300 0 0 2 -1                     
   2: 00000000:006F 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 7876 1 ffff8802f2248000 300 0 0 2 -1                      
   3: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 8163 1 ffff8802f3578000 300 0 0 2 -1                      
   4: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 981582 1 ffff8800d7a53600 300 0 0 2 -1                    
   5: 00000000:0019 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 9129 1 ffff8802edc886c0 300 0 0 2 -1                      
   6: 00000000:021A 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 9016 1 ffff8802edc88000 300 0 0 2 -1                      
   7: 00000000:2B1C 00000000:0000 0A 00000000:00000000 00:00000000 00000000  1026        0 783709 1 ffff8803119cca40 300 0 0 2 -1                    
   8: 00000000:977C 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 24292 1 ffff8802f224e540 300 0 0 2 -1                     

You're looking for lines that have 0A in the st ("status") column. The numbers after the colon in local_address -- C809, 16CC etc -- are TCP port numbers (in hex) on which there are listening processes.

番薯 2024-12-12 08:33:19

我知道我晚了几年,但现有的答案都不够好。

我在谷歌上为完全相同的问题寻找一个好的、优雅的解决方案,但已经发布的答案似乎都不够好,相反,我找到了自己的解决方案,我想将它们发布在这里,以帮助未来被重定向到这里的读者谷歌。

大多数操作系统都有一个名为 netstat 的可执行文件,可用于捕获侦听端口,在本例中我使用的是 Windows 10 和 Python 3.9.6 x64,但这是用 Python 编写的,因此您可以轻松适应它适合您自己的用例。

使用纯 netstat 会非常慢,因为要进行所有名称解析,而使用 netstat -n 会以指数方式更快,因为它不会浪费时间解析名称。

在 Python 3.9.6 中,使用 subproces.run() 运行操作系统调用,并使用 capture_output=True 捕获 stdout,然后使用 .stdout > 结果过程的属性来获取输出,结果是二进制形式,使用.decode()获取字符串。

那么输出应该是这样的:


Active Connections

  Proto  Local Address          Foreign Address        State
  TCP    10.70.0.6:1134         40.83.240.146:443      ESTABLISHED
  TCP    10.70.0.6:1283         117.18.232.200:443     CLOSE_WAIT
  TCP    10.70.0.6:1609         198.252.206.25:443     ESTABLISHED
  TCP    10.70.0.6:1621         198.252.206.25:443     ESTABLISHED
  TCP    10.70.0.6:1691         74.125.24.102:443      ESTABLISHED
  TCP    10.70.0.6:1727         142.251.10.94:443      ESTABLISHED
  TCP    10.70.0.6:1728         142.251.10.100:443     TIME_WAIT
  TCP    10.70.0.6:1731         172.217.194.119:443    TIME_WAIT
  TCP    10.70.0.6:1735         74.125.24.113:443      ESTABLISHED
  TCP    10.70.0.6:1787         104.244.42.130:443     ESTABLISHED
  TCP    10.70.0.6:1796         151.101.1.69:443       ESTABLISHED
  TCP    10.70.0.6:1797         151.101.196.193:443    ESTABLISHED
  TCP    10.70.0.6:1799         74.125.130.132:443     ESTABLISHED
  TCP    10.70.0.6:1800         198.252.206.25:443     ESTABLISHED
  TCP    10.70.0.6:1805         3.209.45.230:443       TIME_WAIT
  TCP    10.70.0.6:1806         3.219.6.82:443         TIME_WAIT
  TCP    10.70.0.6:1807         3.211.239.214:443      TIME_WAIT
  TCP    10.70.0.6:1816         140.82.113.26:443      ESTABLISHED
  TCP    127.0.0.1:1053         127.0.0.1:1055         ESTABLISHED
  TCP    127.0.0.1:1055         127.0.0.1:1053         ESTABLISHED
  TCP    127.0.0.1:1057         127.0.0.1:1058         ESTABLISHED
  TCP    127.0.0.1:1058         127.0.0.1:1057         ESTABLISHED
  TCP    127.0.0.1:1061         127.0.0.1:1062         ESTABLISHED
  TCP    127.0.0.1:1062         127.0.0.1:1061         ESTABLISHED
  TCP    127.0.0.1:1763         127.0.0.1:1764         ESTABLISHED
  TCP    127.0.0.1:1764         127.0.0.1:1763         ESTABLISHED
  TCP    127.0.0.1:1766         127.0.0.1:1767         ESTABLISHED
  TCP    127.0.0.1:1767         127.0.0.1:1766         ESTABLISHED
  TCP    127.0.0.1:1810         127.0.0.1:2015         ESTABLISHED
  TCP    127.0.0.1:1811         127.0.0.1:2015         ESTABLISHED
  TCP    127.0.0.1:1820         127.0.0.1:1821         ESTABLISHED
  TCP    127.0.0.1:1821         127.0.0.1:1820         ESTABLISHED
  TCP    127.0.0.1:1829         127.0.0.1:9614         SYN_SENT
  TCP    127.0.0.1:2015         127.0.0.1:1810         ESTABLISHED
  TCP    127.0.0.1:2015         127.0.0.1:1811         ESTABLISHED
  TCP    127.0.0.1:14845        127.0.0.1:14846        ESTABLISHED
  TCP    127.0.0.1:14846        127.0.0.1:14845        ESTABLISHED
  TCP    127.0.0.1:15004        127.0.0.1:15005        ESTABLISHED
  TCP    127.0.0.1:15005        127.0.0.1:15004        ESTABLISHED
  TCP    127.0.0.1:15013        127.0.0.1:15014        ESTABLISHED
  TCP    127.0.0.1:15014        127.0.0.1:15013        ESTABLISHED
  TCP    127.0.0.1:16976        127.0.0.1:16977        ESTABLISHED
  TCP    127.0.0.1:16977        127.0.0.1:16976        ESTABLISHED
  TCP    127.0.0.1:19278        127.0.0.1:19279        ESTABLISHED
  TCP    127.0.0.1:19279        127.0.0.1:19278        ESTABLISHED
  TCP    127.0.0.1:19280        127.0.0.1:19281        ESTABLISHED
  TCP    127.0.0.1:19281        127.0.0.1:19280        ESTABLISHED
  TCP    127.0.0.1:20695        127.0.0.1:21385        ESTABLISHED
  TCP    127.0.0.1:21385        127.0.0.1:20695        ESTABLISHED
  TCP    127.0.0.1:23460        127.0.0.1:23461        ESTABLISHED
  TCP    127.0.0.1:23461        127.0.0.1:23460        ESTABLISHED
  TCP    127.0.0.1:23462        127.0.0.1:23463        ESTABLISHED
  TCP    127.0.0.1:23463        127.0.0.1:23462        ESTABLISHED
  TCP    127.0.0.1:28343        127.0.0.1:28344        ESTABLISHED
  TCP    127.0.0.1:28344        127.0.0.1:28343        ESTABLISHED
  TCP    127.0.0.1:30307        127.0.0.1:30308        ESTABLISHED
  TCP    127.0.0.1:30308        127.0.0.1:30307        ESTABLISHED
  TCP    127.0.0.1:30311        127.0.0.1:30312        ESTABLISHED
  TCP    127.0.0.1:30312        127.0.0.1:30311        ESTABLISHED
  TCP    127.0.0.1:30313        127.0.0.1:30314        ESTABLISHED
  TCP    127.0.0.1:30314        127.0.0.1:30313        ESTABLISHED
  TCP    127.0.0.1:30316        127.0.0.1:30317        ESTABLISHED
  TCP    127.0.0.1:30317        127.0.0.1:30316        ESTABLISHED
  TCP    127.0.0.1:30319        127.0.0.1:30320        ESTABLISHED
  TCP    127.0.0.1:30320        127.0.0.1:30319        ESTABLISHED
  TCP    127.0.0.1:30584        127.0.0.1:30585        ESTABLISHED
  TCP    127.0.0.1:30585        127.0.0.1:30584        ESTABLISHED
  TCP    127.0.0.1:30623        127.0.0.1:30624        ESTABLISHED
  TCP    127.0.0.1:30624        127.0.0.1:30623        ESTABLISHED
  TCP    127.0.0.1:49669        127.0.0.1:49670        ESTABLISHED
  TCP    127.0.0.1:49670        127.0.0.1:49669        ESTABLISHED
  TCP    127.0.0.1:49690        127.0.0.1:49692        ESTABLISHED
  TCP    127.0.0.1:49692        127.0.0.1:49690        ESTABLISHED
  TCP    [::1]:3306             [::1]:23468            ESTABLISHED
  TCP    [::1]:3306             [::1]:23469            ESTABLISHED
  TCP    [::1]:23468            [::1]:3306             ESTABLISHED
  TCP    [::1]:23469            [::1]:3306             ESTABLISHED

使用 splitlines() 来获取单独的行,然后使用列表切片来获取实际表的内容,这里我们使用索引 4,然后使用正则表达式分割来分割空格字符,然后使用索引来获取本地地址值,最后使用冒号上的字符串分割和索引来获取端口。

代码:

import psutil
import re
import subprocess

def get_active_ports():
    process = subprocess.run(['netstat', '-n'], capture_output=True)
    report = process.stdout.decode().splitlines()
    ports = set()
    for i in report[4:]:
        ports.add(re.split(':(?!.*:)', re.split('\s+', i)[2])[1])
    return ports

或者简单地说:

set([re.split(':(?!.*:)', re.split('\s+', i)[2])[1] for i in subprocess.run(['netstat', '-n'], capture_output=True).stdout.decode().splitlines()[4:]])

性能:

In [119]: %timeit set([re.split(':(?!.*:)', re.split('\s+', i)[2])[1] for i in subprocess.run(['netstat', '-n'], capture_output=True).stdout.decode().splitlines()[4:]])
11.4 ms ± 315 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

或者,psutil 有一个 .net_connections() 方法,您可以从中获取端口。

只需使用集合理解来获取输出:

set(i.laddr.port for i in psutil.net_connections())

这种方法比前一种方法要快得多:

In [103]: %timeit set(i.laddr.port for i in psutil.net_connections())
893 µs ± 13.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

I know I am several years late, but non of the existing answers are good enough.

I was Google searching for a good, elegant solution for exactly the same problem and non of the answers already posted seemed good enough, instead I have found solutions of my own and I want to post them here to help future readers who get redirected here by Google.

Most operating systems have an executable named netstat, that can be used to capture listening ports, in this example I am using Windows 10 and Python 3.9.6 x64, but this is written Python so you can easily adapt it for your own use case.

Using plain netstat will be very slow, because of all the name-resolving, using netstat -n will be exponentially faster because it doesn't waste time resolving the names.

In Python 3.9.6, use subproces.run() to run os calls, and use capture_output=True to capture stdout, then use .stdout property of resultant process to get output, the result is in binary form, use .decode() to get string.

Then the output should look like this:


Active Connections

  Proto  Local Address          Foreign Address        State
  TCP    10.70.0.6:1134         40.83.240.146:443      ESTABLISHED
  TCP    10.70.0.6:1283         117.18.232.200:443     CLOSE_WAIT
  TCP    10.70.0.6:1609         198.252.206.25:443     ESTABLISHED
  TCP    10.70.0.6:1621         198.252.206.25:443     ESTABLISHED
  TCP    10.70.0.6:1691         74.125.24.102:443      ESTABLISHED
  TCP    10.70.0.6:1727         142.251.10.94:443      ESTABLISHED
  TCP    10.70.0.6:1728         142.251.10.100:443     TIME_WAIT
  TCP    10.70.0.6:1731         172.217.194.119:443    TIME_WAIT
  TCP    10.70.0.6:1735         74.125.24.113:443      ESTABLISHED
  TCP    10.70.0.6:1787         104.244.42.130:443     ESTABLISHED
  TCP    10.70.0.6:1796         151.101.1.69:443       ESTABLISHED
  TCP    10.70.0.6:1797         151.101.196.193:443    ESTABLISHED
  TCP    10.70.0.6:1799         74.125.130.132:443     ESTABLISHED
  TCP    10.70.0.6:1800         198.252.206.25:443     ESTABLISHED
  TCP    10.70.0.6:1805         3.209.45.230:443       TIME_WAIT
  TCP    10.70.0.6:1806         3.219.6.82:443         TIME_WAIT
  TCP    10.70.0.6:1807         3.211.239.214:443      TIME_WAIT
  TCP    10.70.0.6:1816         140.82.113.26:443      ESTABLISHED
  TCP    127.0.0.1:1053         127.0.0.1:1055         ESTABLISHED
  TCP    127.0.0.1:1055         127.0.0.1:1053         ESTABLISHED
  TCP    127.0.0.1:1057         127.0.0.1:1058         ESTABLISHED
  TCP    127.0.0.1:1058         127.0.0.1:1057         ESTABLISHED
  TCP    127.0.0.1:1061         127.0.0.1:1062         ESTABLISHED
  TCP    127.0.0.1:1062         127.0.0.1:1061         ESTABLISHED
  TCP    127.0.0.1:1763         127.0.0.1:1764         ESTABLISHED
  TCP    127.0.0.1:1764         127.0.0.1:1763         ESTABLISHED
  TCP    127.0.0.1:1766         127.0.0.1:1767         ESTABLISHED
  TCP    127.0.0.1:1767         127.0.0.1:1766         ESTABLISHED
  TCP    127.0.0.1:1810         127.0.0.1:2015         ESTABLISHED
  TCP    127.0.0.1:1811         127.0.0.1:2015         ESTABLISHED
  TCP    127.0.0.1:1820         127.0.0.1:1821         ESTABLISHED
  TCP    127.0.0.1:1821         127.0.0.1:1820         ESTABLISHED
  TCP    127.0.0.1:1829         127.0.0.1:9614         SYN_SENT
  TCP    127.0.0.1:2015         127.0.0.1:1810         ESTABLISHED
  TCP    127.0.0.1:2015         127.0.0.1:1811         ESTABLISHED
  TCP    127.0.0.1:14845        127.0.0.1:14846        ESTABLISHED
  TCP    127.0.0.1:14846        127.0.0.1:14845        ESTABLISHED
  TCP    127.0.0.1:15004        127.0.0.1:15005        ESTABLISHED
  TCP    127.0.0.1:15005        127.0.0.1:15004        ESTABLISHED
  TCP    127.0.0.1:15013        127.0.0.1:15014        ESTABLISHED
  TCP    127.0.0.1:15014        127.0.0.1:15013        ESTABLISHED
  TCP    127.0.0.1:16976        127.0.0.1:16977        ESTABLISHED
  TCP    127.0.0.1:16977        127.0.0.1:16976        ESTABLISHED
  TCP    127.0.0.1:19278        127.0.0.1:19279        ESTABLISHED
  TCP    127.0.0.1:19279        127.0.0.1:19278        ESTABLISHED
  TCP    127.0.0.1:19280        127.0.0.1:19281        ESTABLISHED
  TCP    127.0.0.1:19281        127.0.0.1:19280        ESTABLISHED
  TCP    127.0.0.1:20695        127.0.0.1:21385        ESTABLISHED
  TCP    127.0.0.1:21385        127.0.0.1:20695        ESTABLISHED
  TCP    127.0.0.1:23460        127.0.0.1:23461        ESTABLISHED
  TCP    127.0.0.1:23461        127.0.0.1:23460        ESTABLISHED
  TCP    127.0.0.1:23462        127.0.0.1:23463        ESTABLISHED
  TCP    127.0.0.1:23463        127.0.0.1:23462        ESTABLISHED
  TCP    127.0.0.1:28343        127.0.0.1:28344        ESTABLISHED
  TCP    127.0.0.1:28344        127.0.0.1:28343        ESTABLISHED
  TCP    127.0.0.1:30307        127.0.0.1:30308        ESTABLISHED
  TCP    127.0.0.1:30308        127.0.0.1:30307        ESTABLISHED
  TCP    127.0.0.1:30311        127.0.0.1:30312        ESTABLISHED
  TCP    127.0.0.1:30312        127.0.0.1:30311        ESTABLISHED
  TCP    127.0.0.1:30313        127.0.0.1:30314        ESTABLISHED
  TCP    127.0.0.1:30314        127.0.0.1:30313        ESTABLISHED
  TCP    127.0.0.1:30316        127.0.0.1:30317        ESTABLISHED
  TCP    127.0.0.1:30317        127.0.0.1:30316        ESTABLISHED
  TCP    127.0.0.1:30319        127.0.0.1:30320        ESTABLISHED
  TCP    127.0.0.1:30320        127.0.0.1:30319        ESTABLISHED
  TCP    127.0.0.1:30584        127.0.0.1:30585        ESTABLISHED
  TCP    127.0.0.1:30585        127.0.0.1:30584        ESTABLISHED
  TCP    127.0.0.1:30623        127.0.0.1:30624        ESTABLISHED
  TCP    127.0.0.1:30624        127.0.0.1:30623        ESTABLISHED
  TCP    127.0.0.1:49669        127.0.0.1:49670        ESTABLISHED
  TCP    127.0.0.1:49670        127.0.0.1:49669        ESTABLISHED
  TCP    127.0.0.1:49690        127.0.0.1:49692        ESTABLISHED
  TCP    127.0.0.1:49692        127.0.0.1:49690        ESTABLISHED
  TCP    [::1]:3306             [::1]:23468            ESTABLISHED
  TCP    [::1]:3306             [::1]:23469            ESTABLISHED
  TCP    [::1]:23468            [::1]:3306             ESTABLISHED
  TCP    [::1]:23469            [::1]:3306             ESTABLISHED

Use splitlines() to get separate lines, then use list slicing to get the contents of the actual table, here we use index 4, then using regex splitting to split on whitespace characters, then use index to get the local address value, then finally use string split on colons and indexing to get the ports.

The code:

import psutil
import re
import subprocess

def get_active_ports():
    process = subprocess.run(['netstat', '-n'], capture_output=True)
    report = process.stdout.decode().splitlines()
    ports = set()
    for i in report[4:]:
        ports.add(re.split(':(?!.*:)', re.split('\s+', i)[2])[1])
    return ports

Or in one-liner:

set([re.split(':(?!.*:)', re.split('\s+', i)[2])[1] for i in subprocess.run(['netstat', '-n'], capture_output=True).stdout.decode().splitlines()[4:]])

Performance:

In [119]: %timeit set([re.split(':(?!.*:)', re.split('\s+', i)[2])[1] for i in subprocess.run(['netstat', '-n'], capture_output=True).stdout.decode().splitlines()[4:]])
11.4 ms ± 315 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Or, alternatively, psutil has a .net_connections() method, you can just get the ports from it.

Just use set comprehension to grab the output:

set(i.laddr.port for i in psutil.net_connections())

This approach is tremendously faster than the previous one:

In [103]: %timeit set(i.laddr.port for i in psutil.net_connections())
893 µs ± 13.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文