【问题标题】:Multiple threads for port scanning?端口扫描的多个线程?
【发布时间】:2022-01-18 18:37:43
【问题描述】:

我在python中编写了以下小脚本,它扫描打开的tcp端口但运行缓慢,我想通过使用线程来提高性能,我该如何实现这样的功能?

socket.setdefaulttimeout(0.01)
    for port in range(0, 65536):
        s = None
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        if s.connect_ex((sys.argv[1], port)) == 0:
            open_ports.append(port)
        s.close()

我想通过变量设置线程数。

【问题讨论】:

    标签: python python-3.x multithreading networking port


    【解决方案1】:

    由于 python 是“最慢”的语言之一,并且您想要执行的操作很简单,我建议您使用 c lang 或任何其他中低级语言。
    在我看来,使用多线程来提高自然慢速语言的速度只是徒劳的。

    网上有很多例子,我建议你检查一下 https://codereview.stackexchange.com/questions/85553/simple-c-port-scanner

    【讨论】:

    • OP除了使用Python的性能之外可能还有其他原因......
    【解决方案2】:

    我会写这样的:

    import socket
    from multiprocessing.pool import ThreadPool
    
    def check_socket(host, port):
        socket.setdefaulttimeout(0.01)
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            # return port if open, None otherwise
            return port if s.connect_ex((host, port)) == 0 else None
    
    
    def main(host):
        with ThreadPool() as pool:
            result = pool.starmap(check_socket, ((host, port) for port in range(0, 65536)))
            # Pull out the list of open ports
            return [x for x in result if x is not None]
    

    【讨论】:

      【解决方案3】:

      将您的代码放入函数 start_scan(port_range)

      并检查 asyncio 库:

      asyncio.create_task(start_scan(port_range))
      

      然后你可以有一个你想要的线程数的循环,你可以创建尽可能多的任务。 然后你一个一个地等待它们,或者收集它们。

      https://docs.python.org/3/library/asyncio-task.html

      ======= 编辑 =======
      要回答这个问题,如何在子列表中拆分范围:

      import math
      
      def split_ports(ports, threads):
          ports_per_threads = [[]]
          n_port_per_thread = math.ceil(len(ports)/threads)
      
          i = 0
          t = 0
          for p in ports:
              i+=1
              if (i > n_port_per_thread):
                  i = 0
                  t += 1
                  ports_per_threads.append(list())
              ports_per_threads[t].append(p)
      
      ports = range(100, 200)
      ports_lists = split_ports(ports, 4)
      

      这会给你这个结果:

      ports = range(1, 9)
      ports_lists = split_ports(ports, 4)
      # -> [[1, 2], [3, 4], [5, 6], [7, 8]]
      ports_lists = split_ports(ports, 2)
      # -> [[1, 2, 3, 4], [5, 6, 7, 8]]
      

      【讨论】:

      • 我不想为每个端口创建线程...
      • 不,你给了一个端口范围。然后您将其拆分为您拥有的线程数。
      • 怎么做?加上所有线程都添加到同一个列表中......
      • @Ariel:由于列表将是共享资源,因此您需要使用互斥锁来控制对它的并发访问。
      • 不一定,所有端口的扫描时间都差不多,只是事先将它们分开。您可以对它们进行迭代以将它们分隔在二维列表中。 (1= 线程,2= 端口)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多