title: improve the throughput of sending multiple file via socket
body: <p>At First, I don't have any errors or bugs, I ask this question to understand more.
  I want to send multiple files concurrently via a separate connection to a server from a client. I used threads to make the sending process concurrent on the client-side. It sounds that it does improve the throughput a little bit. But I'm still confused. below is my server and client code. I don't know how using threads makes this process concurrent, because the socket on the server-side has a queue, and all the data stash in the queue whether they were sent in turn or concurrently. Can anyone explain it to me? or if I am wrong or my code doesn't make sending concurrent, please let me know! thanks.</p>
  <p>server.py</p>
  <pre><code>    def rcv_thread(self, conn):
          context = ''
          while True:
              try:
                  recvfile = conn.recv(4096)
                  context += recvfile.decode()
              except Exception:
                  if context == '':
                      return
                  break
          
        /////////
          conn.close()
  
      def receive(self):
          self.t = time.time()
          while True:
              c, addr = self.socket.accept()
              c.settimeout(2)
              start_new_thread(self.rcv_thread,(c,))
  
  
  </code></pre>
  <p>client.py</p>
  <pre><code>    def transfer_file(self, file_name):
          path = self.path + &quot;/&quot; + file_name
          sckt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
          sckt.connect((self.HOST, self.PORT))
          file = open(path, 'rb')
          context = file.read()
          sckt.sendall((file_name + &quot;##&quot; + context.decode()).encode())
          sckt.close()
  
      def run(self):
          self.start_time = time.time()
          files = os.listdir(self.path)
          num_of_iterates = int(len(files) / self.concurrency)
          for j in range(num_of_iterates + 1):
              min_iter = min(self.concurrency, len(files) - j * self.concurrency)
              for i in range(min_iter):
                  th = threading.Thread(target=self.transfer_file, args={files[j * self.concurrency + i]})
                  th.start()
                  self.connection_threads.append(th)
  
              for i in range(min_iter):
                  self.connection_threads[i].join()
  
  </code></pre>