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

IP段端口扫描遍历时报TypeError:需字符串/缓冲区却传入IPv4Address

解决TypeError: coercing to Unicode: need string or buffer, IPv4Address found端口扫描问题

这个问题我之前做网段扫描的时候也踩过坑,本质原因很简单:你用ipaddress模块生成的IP对象,没办法直接传给socket的接口——socket.connect_ex()需要的是字符串格式的IP地址,而ipaddress返回的是IPv4Address类的实例,类型不匹配就触发了这个错误。

错误原因拆解

当你遍历ipaddress.IPv4Network生成的网段时,每个元素都是IPv4Address对象,比如:

for ip in ipaddress.IPv4Network('192.168.1.0/24'):
    print(type(ip))  # 输出 <class 'ipaddress.IPv4Address'>

而socket的connect_ex((host, port))要求host必须是字符串或者字节流,直接传对象自然会报错。

两种解决方案

方案1:调用扫描函数时转成字符串

在遍历网段、调用portscan的时候,用str()把IP对象转成字符串:

# 示例遍历网段的代码
network = ipaddress.IPv4Network('192.168.1.0/24', strict=False)
for ip in network.hosts():
    portscan(str(ip))  # 这里把IPv4Address转成字符串

方案2:在扫描函数内部统一处理

更稳妥的方式是在portscan函数开头就把传入的host转成字符串,这样不管外部传的是字符串还是IP对象都能兼容:

def portscan(host):
    # 新增:将host转换为字符串格式
    host = str(host)
    try:
        for port in range(1,445):
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            # 可选优化:设置超时时间,大幅提升扫描速度
            sock.settimeout(0.5)
            result = sock.connect_ex((host, port))
            if result == 0:
                print "port",port," is open on",host
            sock.close()
    except KeyboardInterrupt:
        print " CTRL+C Interrupt..."
        sys.exit()  # 中断后退出程序,更友好

修改后的完整可运行代码

#!/usr/bin/env python
import socket
import ipaddress
import sys

def portscan(host):
    host = str(host)
    try:
        for port in range(1,445):
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(0.5)
            result = sock.connect_ex((host, port))
            if result == 0:
                print "port",port," is open on",host
            sock.close()
    except KeyboardInterrupt:
        print " CTRL+C Interrupt..."
        sys.exit()

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print "Usage: python port_scan.py <network_cidr>"
        print "Example: python port_scan.py 192.168.1.0/24"
        sys.exit(1)
    try:
        network = ipaddress.IPv4Network(sys.argv[1], strict=False)
        for ip in network.hosts():
            portscan(ip)
    except ValueError:
        print "Invalid CIDR format, please check your input."
        sys.exit(1)

额外优化提示

  • 加上超时时间:默认socket连接没有超时,会导致扫描关闭的端口时等待很久,sock.settimeout(0.5)可以让扫描效率提升很多。
  • 增加命令行参数支持:上面的完整代码加入了CIDR参数输入,使用更灵活。
  • 如果是Python3环境,记得把print语句改成带括号的函数形式,比如print(f"port {port} is open on {host}")。

内容的提问来源于stack exchange,提问作者Brandon McGrath

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:28:53