You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Socket扫描始终返回‘端口关闭’,但实际端口已开放问题排查

解决Python端口扫描程序始终显示“端口关闭”的问题

我帮你排查了代码里的几个关键问题,正是这些问题导致明明开放的端口被误判为关闭:

核心问题1:端口参数是字符串而非整数

你通过argparse获取的端口列表targetPort是字符串类型,但socket.connect()要求端口必须是整数。当你把字符串端口传给socket时,会直接触发连接异常,最终走到except分支输出“端口关闭”。

核心问题2:Socket资源管理有漏洞

在connect_scan.py的finally块中,如果你连接失败(比如因为端口类型错误),sock对象根本没被创建就执行sock.close(),这会额外抛出NameError,影响程序稳定性。

核心问题3:参数校验逻辑有隐患

在get_target.py中,当用户未指定-p参数时,target_ports是None,此时访问target_ports[0]会直接报错,而不是友好提示用户补全参数。


修正后的完整代码

1. get_target.py(修复参数类型与校验)

import argparse

def get_target():
    parser = argparse.ArgumentParser(description='Usage of program: ' + '-H <target host> -p <target port>')
    parser.add_argument('-H', dest='targetHost', required=True, help='specify target host')
    parser.add_argument('-p', dest='targetPort', nargs='*', type=int, help='specify target ports separated by space')
    args = parser.parse_args()
    
    target_host = args.targetHost
    target_ports = args.targetPort
    
    # 改进参数校验:直接检查target_ports是否为空
    if not target_ports:
        print("Error: Please specify at least one target port with -p")
        print(parser.usage)
        exit(0)
    
    return target_host, target_ports
  • 新增type=int让argparse自动把端口转为整数
  • 替换原有的target_ports[0]判断,直接检查列表是否为空,避免None索引错误

2. connect_scan.py(修复Socket资源管理)

import socket

def connect_scan(target_host, target_port):
    sock = None
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 添加超时,避免程序卡住(比如目标主机无响应)
        sock.settimeout(1)
        sock.connect((target_host, target_port))
        print('[+] {}/tcp open'.format(target_port))
    except socket.timeout:
        print('[-] {}/tcp timed out'.format(target_port))
    except ConnectionRefusedError:
        print('[-] {}/tcp closed'.format(target_port))
    except Exception as e:
        print('[-] {}/tcp error: {}'.format(target_port, str(e)))
    finally:
        if sock:
            sock.close()
  • 初始化sock为None,避免finally块中访问未定义的变量
  • 添加超时设置,防止线程长时间阻塞
  • 拆分异常类型,区分超时、连接拒绝和其他错误,输出更精准的信息

3. port_scan.py(优化流程逻辑)

from socket import *
from threading import *
from .get_target import *
from .connect_scan import *

def port_scan():
    target_host, target_ports = get_target()
    try:
        target_ip = gethostbyname(target_host)
    except:
        print('Unknown host {}'.format(target_host))
        return  # 提前退出,避免后续错误
    
    try:
        target_name = gethostbyaddr(target_ip)
        print('[+] Scan results for: ' + target_name[0])
    except:
        print('[+] Scan results for: ' + target_ip)
    
    for target_port in target_ports:
        t = Thread(target=connect_scan, args=(target_ip, target_port))
        t.start()
  • 解构get_target()的返回值,代码更清晰
  • 在Unknown host后添加return,避免后续代码继续执行

测试运行

现在你可以用以下命令测试(替换为你的Metasploitable主机IP):

python main.py -H 192.168.1.100 -p 21 22 80 443

这时候应该能正确显示开放的端口了,和Nmap的结果一致。

内容的提问来源于stack exchange,提问作者Jimin Byun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:10:34