我写了一个小螺纹端口扫描仪,在我完成它之后我注意关闭插座。
尽管关闭了套接字,但是当我针对大量目标主机运行时出现Too many open files
错误(~12' 000主机和5个端口,总共60个&# 39; 000个套接字创建/关闭)。
我的理解是我应该只在关闭端口时遇到此错误。我对那些要求我修改系统可以处理的打开文件数量的选项并不感兴趣(在其他SO帖子中推荐)。
以下全端扫描程序代码。
import socket
import itertools
from concurrent.futures import ThreadPoolExecutor, as_completed
def check_port(host, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
if sock.connect_ex((host, port)) == 0:
sock.close()
return host, port
sock.close()
return False
hosts = open('/tmp/hosts').read().splitlines()
ports = [80, 443, 8000, 8080, 8443]
with ThreadPoolExecutor(max_workers=100) as executor:
future_to_host_port = [
executor.submit(check_port, host, port)
for host, port in itertools.product(hosts, ports)
]
for future in as_completed(future_to_host_port):
try:
result = future.result()
if not result:
continue
print(result)
except socket.gaierror as e:
print(f'couldn\'t resolve')
except socket.timeout as e:
print(f'socket timeout')
except Exception as e:
print(type(e))
print(f'error {e}')
答案 0 :(得分:0)
不确定这是导致您的具体问题的原因,但您对close()
的调用应位于finally块内。来自connect_ex
的文档:
与connect(address)类似,但是返回错误指示符而不是为C级connect()调用返回的错误引发异常(其他问题,例如“找不到主机”,仍然会引发异常强>)。
对我而言,如果您正在扫描12,000台主机,其中一些主机不存在而且您为每台主机泄漏了一个插槽(或5)。
试试这个:
def check_port(host, port):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.settimeout(1)
if sock.connect_ex((host, port)) == 0:
return host, port
return False