制作扫描奇数IP的端口扫描器遇报错:str, bytes or bytearray expected, not int
解决端口扫描器的类型错误问题
让我们来拆解你遇到的str, bytes or bytearray expected, not int错误,以及那些容易被忽略的细节问题:
错误根源分析
你的代码里有两个关键的类型不匹配问题,这是导致报错的核心原因:
- 端口参数类型错误:
port是通过input()获取的,默认是字符串类型,但socket.connect()的第二个参数要求必须是整数类型的端口号,这是触发错误的主要原因。 - IP地址的不必要转换:
int(ipaddress.ip_address(my_net[i]))把IP地址转换成了整数形式(比如192.168.1.1会变成3232235777),虽然socket底层支持整数IP,但这完全没必要,直接用字符串格式的IP更直观也不容易出错。
除此之外,代码还遗漏了几个细节:
- 没有处理
s.recv()返回空数据的情况,可能会导致输出异常 - 每次循环都创建新的socket对象,虽能运行但可以优化
- 扫描完成后没有关闭socket连接,会占用系统资源
修复后的完整代码
import socket from datetime import datetime # 获取子网输入 subnet = input("Which subnet are you scanning? Please enter in x.x.x format: ") my_net = [] # 生成11-255范围内的奇数IP(注意range左闭右开,要包含255需写256) for i in range(11, 256): if i % 2 != 0: my_net.append(f"{subnet}.{i}") print(f"Your selected network is {subnet}\nBelow are the usable IP addresses:") for ip in my_net: print(ip) # 获取端口并做合法性校验 while True: try: port = int(input("\nEnter the number of the port you would like to scan: ")) if 1 <= port <= 65535: break else: print("Port must be between 1 and 65535. Try again.") except ValueError: print("Please enter a valid integer port number.") # 扫描前的信息输出 print("-" * 60) print(f"Please wait, scanning network {subnet}.0/24 on port {port}") print("-" * 60) # 记录扫描开始时间 t1 = datetime.now() # 遍历所有目标IP进行扫描 for ip in my_net: try: socket.setdefaulttimeout(2) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 使用字符串IP和整数端口建立连接 s.connect((ip, port)) # 接收服务banner并处理编码问题 banner = s.recv(1024) if banner: # 尝试用UTF-8解码,失败则输出原始字节数据 try: print(f"[+] {ip}:{port} - {banner.decode('utf-8').strip()}") except UnicodeDecodeError: print(f"[+] {ip}:{port} - Raw banner: {banner}") else: print(f"[+] {ip}:{port} - Port is open (no banner received)") s.close() # 关闭连接释放资源 except Exception as e: print(f"[-] {ip}:{port} - Error: {e}") # 计算并输出扫描耗时 t2 = datetime.now() total = t2 - t1 print(f"\nScanning Completed in: {total}")
关键修复点说明
- 端口类型转换:用
int()把输入的端口字符串转换成整数,同时增加了合法性校验,确保端口在1-65535的有效范围内。 - IP地址使用优化:直接使用生成的字符串格式IP,去掉了不必要的
ipaddress转换(如果需要校验IP合法性,可以保留ipaddress.ip_address(ip)验证,但无需转成整数)。 - 资源清理:每次扫描后调用
s.close()关闭socket连接,避免资源泄漏。 - 用户体验优化:增加了IP列表输出、端口合法性校验,以及banner的编码处理,减少乱码问题。
内容的提问来源于stack exchange,提问作者Lachie Wright
相关产品推荐
相关产品推荐

