Python:如何检查网络端口是否在Linux上打开?

Fat*_*ima 62 python linux port netstat

我如何知道某个端口是否在linux ubuntu上打开/关闭,而不是远程系统,使用python?如何在python中列出这些开放端口?

  • Netstat:有没有办法将netstat输出与python集成?

小智 114

您可以使用套接字模块来检查端口是否打开.

它看起来像这样.

import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex(('127.0.0.1',80))
if result == 0:
   print "Port is open"
else:
   print "Port is not open"
sock.close()
Run Code Online (Sandbox Code Playgroud)

  • 这有明显的缺点需要注意:只是尝试检查连接可能1)由于防火墙或临时溢出而失败,2)在任何主动保护的情况下触发对连接尝试的不必要的反应,3)简单地破坏日志和统计信息.使用特殊专用工具作为netstat进行检查通常是首选. (10认同)
  • @Netch - 当你在一个盒子上,你不想安装额外的工具并且需要检查远程端口是否打开时,这非常方便... (4认同)
  • 也适用于Windows. (3认同)

Mic*_*ael 70

如果要在更一般的上下文中使用它,则应确保打开的套接字也已关闭.所以检查应该更像这样:

import socket
from contextlib import closing

def check_socket(host, port):
    with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
        if sock.connect_ex((host, port)) == 0:
            print "Port is open"
        else:
            print "Port is not open"
Run Code Online (Sandbox Code Playgroud)

  • 赞成提及[自动资源管理](https://www.python.org/dev/peps/pep-0343/).更多人需要看到这个! (8认同)
  • @plumSemPy 我的答案是为 python2 编写的。在 python3 中,套接字已经用作上下文管理器。所以如果bind适合你,那就完美了。 (2认同)

小智 33

对我来说,如果端口未打开,上面的示例将会挂起.第4行显示了使用settimeout来防止挂起

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(2)                                      #2 Second Timeout
result = sock.connect_ex(('127.0.0.1',80))
if result == 0:
  print 'port OPEN'
else:
  print 'port CLOSED, connect_ex returned: '+str(result)
Run Code Online (Sandbox Code Playgroud)


Joe*_*Joe 18

如果您只关心本地计算机,则可以依赖psutil包.你可以:

  1. 检查特定pid使用的所有端口:

    proc = psutil.Process(pid)
    print proc.connections()
    
    Run Code Online (Sandbox Code Playgroud)
  2. 检查本地计算机上使用的所有端口:

    print psutil.net_connections()
    
    Run Code Online (Sandbox Code Playgroud)

它也适用于Windows.

http://pythonhosted.org/psutil/

  • 我通常避免使用非stdlib解决方案,但是gdi,psutil应该只是在stdlib中,它太必要了. (2认同)

Sac*_*hin 9

我在这篇文章中找到了多种解决方案。但某些解决方案存在挂起问题或在端口未打开的情况下花费太多时间。请尝试以下解决方案:

import socket 

def port_check(HOST):
   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   s.settimeout(2) #Timeout in case of port not open
   try:
      s.connect((HOST, 22)) #Port ,Here 22 is port 
      return True
   except:
      return False

port_check("127.0.1.1")
Run Code Online (Sandbox Code Playgroud)


Ped*_*ito 8

这是一个快速的多线程端口扫描器:

from time import sleep
import socket, ipaddress, threading

max_threads = 50
final = {}
def check_port(ip, port):
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # TCP
        #sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
        socket.setdefaulttimeout(2.0) # seconds (float)
        result = sock.connect_ex((ip,port))
        if result == 0:
            # print ("Port is open")
            final[ip] = "OPEN"
        else:
            # print ("Port is closed/filtered")
            final[ip] = "CLOSED"
        sock.close()
    except:
        final[ip] = "EXCEPTION"
        
port = 22
for ip in ipaddress.IPv4Network('95.217.210.0/24'): 
    threading.Thread(target=check_port, args=[str(ip), port]).start()
    #sleep(0.1)

    # limit the number of threads.
    while threading.active_count() > max_threads :
        sleep(1)


sorted_ips = dict(sorted(final.items(), key=lambda item: tuple(map(int, item[0].split('.')))))

for ip, state in sorted_ips.items():
    print(ip, state)
Run Code Online (Sandbox Code Playgroud)

现场演示


Pit*_*tto 6

刚刚在 mrjandro 的解决方案中添加了一些改进,例如自动资源管理(确保打开的套接字也被关闭)、处理超时、消除简单的连接错误/超时以及打印结果:

import socket
from contextlib import closing

hosts = ["host1", "host2", "host3"]
port = 22
timeout_in_seconds = 2

hosts_with_opened_port = []
hosts_with_closed_port = []
hosts_with_errors = []


def check_port(host, port, timeout_in_seconds):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(timeout_in_seconds)
    with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
        try:
            result = sock.connect_ex((host, port))
            if result == 0:
                print("Port {} is *** OPEN *** on host: {}".format(port, host))
                hosts_with_opened_port.append(host)
            else:
                print("Port {} is not open on host: {}".format(port, host))
                hosts_with_closed_port.append(host)
        except socket.gaierror:
            print("Port {} check returns a network *** ERROR *** on host: {}".format(port, host))
            hosts_with_errors.append(host)


for host in hosts:
    check_port(host, port, timeout_in_seconds)

print("\nHosts with opened port:")
print(hosts_with_opened_port)
print("\nHosts with closed port:")
print(hosts_with_closed_port)
print("\nHosts with errors:")
print(hosts_with_errors)
Run Code Online (Sandbox Code Playgroud)


Ale*_*nko 5

如果您探测 TCP 端口并打算侦听它,最好实际调用侦听。使用 tring 连接的方法是 don\xe2\x80\x99t“查看”已建立连接的客户端端口,因为没有人监听它。但这些端口不能用于监听它。

\n\n
import socket\n\n\ndef check_port(port, rais=True):\n    """ True -- it\'s possible to listen on this port for TCP/IPv4 or TCP/IPv6\n    connections. False -- otherwise.\n    """\n    try:\n        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n        sock.bind((\'127.0.0.1\', port))\n        sock.listen(5)\n        sock.close()\n        sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)\n        sock.bind((\'::1\', port))\n        sock.listen(5)\n        sock.close()\n    except socket.error as e:\n        return False\n        if rais:\n            raise RuntimeError(\n                "The server is already running on port {0}".format(port))\n    return True\n
Run Code Online (Sandbox Code Playgroud)\n

  • 使用像 5 这样的“神奇数字”而不加注释是不好的做法。根据文档,这个参数 socket.socket.listen(backlog) 是“系统允许的不接受连接的数量”。目前尚不清楚为什么您的解决方案不适用于积压“0”,只是为了测试套接字是否可用于侦听端点。(PS,我比实际尝试连接的解决方案更喜欢你的解决方案) (2认同)

han*_*ast 5

基于psutilJoe 提到的解决方案(仅适用于检查本地端口):

import psutil
1111 in [i.laddr.port for i in psutil.net_connections()]
Run Code Online (Sandbox Code Playgroud)

True如果当前使用端口 1111,则返回。

psutil不是 python stdlib 的一部分,所以你需要pip install psutil首先。它还需要 python 标头可用,因此您需要类似的东西python-devel