线程端口扫描程序:打开的文件太多(关闭套接字后)

时间:2018-01-21 19:47:04

标签: python multithreading sockets port-scanning

我写了一个小螺纹端口扫描仪,在我完成它之后我注意关闭插座。

尽管关闭了套接字,但是当我针对大量目标主机运行时出现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}')

1 个答案:

答案 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