title: Scapy multithreading scans slowly
body: <p>I'm writing a multithreading port scanner using scapy,
  I create a process to use scapy's sniffer, and use multithreading to send syn packet,but I found the maximum speed of a scanner is 100 times per second,it is too slow.
  So I use other way:</p>
  
  <pre><code>response = sr(IP(dst=targetIP)/TCP(dport=port, flags='S', timeout=1))
  </code></pre>
  
  <p>I found sr is slower than using send and sniff</p>
  
  <p>My main code is as follows:</p>
  
  <pre><code>def prn(self,pkt):
      ip = pkt.sprintf('%IP.src%')
      port = pkt.sprintf('%IP.sport%')
      info = '{0}:{1}'.format(ip,port)
      fileipinfo =  '{0}:{1}\n'.format(ip,port)
      if (int(port) in self.portlist) and (info not in self.result):
          self.result.add(info)
          lock.acquire()
          FileHelper.append(self.savepath,fileipinfo)
          model = dict(ip=ip,port=int(port),flag=self.data_flag,createdatetime= datetime.datetime.now())
          SqlHelper.add(model)
          lock.release()
  
  def listen(self,portlist):
      self.portlist = portlist
      sniff(filter="tcp[13:1] &amp; 18==18", prn=self.prn) #iface=self.ifacestr
  
  
  def send(self,param):
      ip = param['ip']
      port = param['port']
      send(IP(dst=ip) / TCP(dport=port, flags='S'), verbose=False)
  
      self.sendcount = self.sendcount + 1
  
      sys.stdout.write('\r' + 'Scanned:{0},Remaining{1}'.format(self.sendcount, self.taskcount - self.sendcount))
      sys.stdout.flush()
  
  
  def run(self):
      time_start = time.time()
      scannerparam = self.scannerparam
      if scannerparam.save:
          RESULT_PATH = scannerparam.save
      params = []
      iplist = IpHelper.get_ip_list(scannerparam)
      portlist = PortHelper.get_port_list(scannerparam)
  
      p_listen = Process(target=self.listen,args=(portlist,))
      p_listen.start()
  
      for ip in iplist:
          for port in portlist:
              params.append({'ip':ip,'port':port})
      self.taskcount = len(params)
  
      with futures.ThreadPoolExecutor(max_workers=scannerparam.threadnum) as executor:
          param_left = len(params)
          param_iter = iter(params)
          jobs = {}
          while(param_left):
              for param in param_iter:
                  job = executor.submit(self.send,param)
                  jobs[job] = param
                  if len(jobs) &gt; scannerparam.threadnum:
                      break
              for job in futures.as_completed(jobs):
                  param_left -= 1
                  #result = job.result()
                  del jobs[job]
                  break
  
      time_end = time.time()
  
      time.sleep(20)
      p_listen.terminate()
  
      if scannerparam.validator:
          self.validate(scannerparam)
  
  def validate(self,scannerparam):
      if 'proxy' in scannerparam.validator:
          proxy_validator = ProxyValidator(self.data_flag)
          p_proxy = Process(target=proxy_validator.run)
          p_proxy.start()
          p_proxy.join()
  </code></pre>