title: Cannot connect large numbers of multithreaded Python sockets (timeout error)
body: <p>I'm writing a port scanner in Python, and the basic code looks like this:</p>
  
  <pre class="lang-py prettyprint-override"><code>import socket
  import sys
  import threading
  
  def scan_port(host, port, timeout):
      addr = str(host), int(port)
      conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      conn.settimeout(float(timeout))
  
      try:
          conn.connect(addr)
          print(f'- {port} open')
      except Exception as error:
          print(f'- {port} closed: {error!r}')
      finally:
          conn.close()
  
  if __name__ == '__main__':
      host = sys.argv[1]
      pmin = int(sys.argv[2])
      pmax = int(sys.argv[3])
  
      threads = []
  
      for port in range(pmin, pmax+1):
          args   = [host, port, 1.0]
          thread = threading.Thread(target=scan_port, args=args)
          thread.start()
          threads.append(thread)
  
      for thread in threads:
          thread.join()
  </code></pre>
  
  <p>When I run this script on a single port, it always connects:</p>
  
  <pre class="lang-sh prettyprint-override"><code>$ python scantest.py google.com 80 80
  - 80 open
  </code></pre>
  
  <p>But when I run it on a large sequence of ports (at least 100), it always fails (with a generic "timeout" error):</p>
  
  <pre class="lang-sh prettyprint-override"><code>$ python scantest.py google.com 1 100
  - 1 closed: timeout('timed out')
  - 2 closed: timeout('timed out')
  - 3 closed: timeout('timed out')
  - 4 closed: timeout('timed out')
  # etc...
  </code></pre>
  
  <p>Is there some quirk of Python that prevents me from multithreading large numbers of socket connections, or am I missing some basic hurdle? I'm running this on Windows 8, if that helps. Thank you.</p>
  
  <p><strong>Edit:</strong> Judging from further research there simply seems to be a limit on how many socket connections a system can attempt at once. I've re-implemented this script with a <code>ThreadPoolExecutor</code> from the <code>concurrent.futures</code> module and it's significantly improved reliability (at the cost of speed). </p>