title: Python - [Errno 10054] An existing connection was forcibly closed by the remote host - sending pickled data issues
body: <p>I followed an online tutorial that showed how to make a rock paper scissors game that can handle multiple clients connecting to a server, allowing multiplayer. The game works so I tried to use the same network logic for a different game but I ran into some errors there. Particularly when using the <code>send</code> function: Using the <code>send</code> function I get an <code>EOFError: Ran out of input</code> error. In this post <a href="https://stackoverflow.com/questions/62361900/online-game-give-the-error-connectionabortederror-winerror-10053">Online game give the error &quot;(&quot;ConnectionAbortedError: [WinError 10053] &quot;</a> I found a supposed fix where the send function waits until it has received all of the data, as it sometimes may have issues when receiving pickled data.</p>
  <p>However, when I replace the <code>send</code> function with the new <code>send2</code> function (temporary name) I run into different errors. Namely: <code>[Errno 10054] An existing connection was forcibly closed by the remote host.</code></p>
  <p>SOLVED, SEE FOLLOWING PARAGRAPh:</p>
  <p>Essentially, what I'm trying to do is replacing my send function (which also receives data) by a better send function that sends pickled data and receives the exact amount of sent information.</p>
  <pre><code>def send(self, data):
      try:
          self.client.send(pickle.dumps(data))
          return pickle.loads(self.client.recv(2048))
      except socket.error as e:
          print(e)
  
  # source: https://stackoverflow.com/questions/62361900/online-game-give-the-error-connectionabortederror-winerror-10053
  def send2(self, data):
      data_to_send = pickle.dumps(data)
      data_size = struct.pack( '!I', len(data_to_send))
      try:
          self.client.send(data_size)
          self.client.send(pickle.dumps(data))
          
          package = self.receive()
          return package
      except socket.error as e:
          print(e)
  
          
  def receive(self):
      packet = None
      buffer = bytes()
      expected = -1
      print(&quot;receiving stuff&quot;)
      while len(buffer) &lt; 4:
          print(&quot;received a buffer&quot;)
          try:
              partial_data = self.client.recv(4 - len(buffer))
              if partial_data:
                   buffer.append(partial_data)
                   if len(buffer) == 4:
                       expected = struct.unpack('!I', buffer)
          except Exception as e:
              print(e)
              break
  
      # If we received a buffer size, try to receive the buffer
      if expected &gt; 0:
          buffer = bytes()
          while len(buffer) &lt; expected: 
              try:
                  partial_data = self.client.recv(expected - len(buffer))
                  if partial_data:
                       buffer.append(partial_data)
                       # Have we received the full data-set yet?
                       if len(buffer) == expected:
                           packet = pickle.loads(buffer)
              except:
                  break
              
      print(packet)
      return packet
  </code></pre>
  <p>I'm assuming I'm overlooking something incredibly easy. If needed, I can post the 4 .py files that run the game. All I need is to create a better <code>send</code> function that doesn't crash the client when it is dealing with sending data that is sometimes not pickle-worthy.</p>
  <p>EDIT:</p>
  <p>Server.py code</p>
  <pre><code>import socket
  import pickle
  from _thread import *
  import sys
  sys.path.append(&quot;C:/Program Files/Hero Realms/Multiplayer/&quot;)
  from game import Game
  from network import Network
  
  server = &quot;&quot; # this is defined but I removed it for this page
  port = 5555
  
  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  
  try:
      s.bind((server, port))
  except socket.error as e:
      print(e)
      
  s.listen(2)
  print(&quot;Waiting for a connection, Server Started&quot;)
  
  connected = set()
  games = {}
  id_count = 0
  
  def threadedClient(conn, p, game_id):
      global id_count 
      conn.send(str.encode(str(p)))
      
      reply = &quot;&quot;
      while True:
          try:
              #data = pickle.loads(conn.recv(4096))
              data = Network.receive(s)
              print(data)
              # check if the game still exists
              if game_id in games:
                  game = games[game_id]
                  
                  if not data:
                      break
                  else:
                      if data == &quot;reset&quot;:
                          game.resetWent()
                      elif data != &quot;get&quot;:
                          game.play(p, data)
                          
                      reply = game
                      conn.sendall(pickle.dumps(reply))
                      
              else:
                  break
          except:
              break
          
      print(&quot;Lost connection&quot;)
      
      try:
          print(&quot;Closing game&quot;, game_id)
          del games[game_id]
      except:
          pass
      
      id_count -=1
      conn.close()
      
      
  while True:
      conn, addr = s.accept()
      print(&quot;Connected to: &quot;, addr)
      
      id_count += 1
      p = 0
      game_id = (id_count - 1) // 2
      
      if id_count % 2 == 1:
          games[game_id] = Game(game_id)
          print(&quot;Creating a new game...&quot;)
      else:
          games[game_id].ready = True
          p = 1
          
      
      start_new_thread(threadedClient, (conn, p, game_id))
  </code></pre>
  <p>Client.py</p>
  <pre><code>import pygame
  
  import sys
  sys.path.append(&quot;C:/Program Files/Hero Realms/Multiplayer/&quot;)
  from network import Network
  import pickle
  
  pygame.font.init()
  pygame.init()
  
  width = 700
  height = 700
  win = pygame.display.set_mode((width, height))
  pygame.display.set_caption(&quot;Client&quot;)
  
  class Button:
      def __init__(self, text, x, y, color):
          self.text = text
          self.x = x
          self.y = y
          self.color = color
          self.width = 150
          self.height = 100
          
      def draw(self, win):
          pygame.draw.rect(win, self.color, (self.x, self.y, self.width, self.height))
          font = pygame.font.SysFont(&quot;comicsans&quot;, 40)
          text = font.render(self.text, 1, (255, 255, 255))
          win.blit(text, (self.x + round(self.width / 2) - round(text.get_width() / 2), self.y + round(self.height / 2) - round(text.get_height() / 2)))
          
      def click(self, pos):
          x1 = pos[0]
          y1 = pos[1]
          
          if self.x &lt;= x1 &lt;= self.x + self.width and self.y &lt;= y1 &lt;= self.y + self.height:
              return True
          else:
              return False
          
  def redrawWindow(win, game, p):
      win.fill((128, 128, 128))
      
      if not(game.connected()):
          font = pygame.font.SysFont(&quot;comicsans&quot;, 80)
          text = font.render(&quot;Waiting for Player...&quot;, 1, (255, 0, 0), True)
          win.blit(text, (width / 2 - text.get_width() / 2, height / 2 - text.get_height() / 2))
      else:
          font = pygame.font.SysFont(&quot;comicsans&quot;, 60)
          text = font.render(&quot;Your Move&quot;, 1, (0, 255, 255))
          win.blit(text, (80, 200))
          
          text = font.render(&quot;Opponents&quot;, 1, (0, 255, 255))
          win.blit(text, (380, 200))
          
          move1 = game.getPlayersMove(0)
          move2 = game.getPlayersMove(1)
          if game.bothWent():
              text1 = font.render(move1, 1, (0, 0, 0))
              text2 = font.render(move2, 1, (0, 0, 0))
          else:
              if game.p1_went and p == 0:
                  text1 = font.render(move1, 1, (0, 0, 0))
              elif game.p1_went:
                  text1 = font.render(&quot;Locked in&quot;, 1, (0, 0, 0))
              else:
                  text1 = font.render(&quot;Waiting...&quot;, 1, (0, 0, 0))
                  
              if game.p2_went and p == 1:
                  text2 = font.render(move2, 1, (0, 0, 0))
              elif game.p2_went:
                  text2 = font.render(&quot;Locked in&quot;, 1, (0, 0, 0))
              else:
                  text2 = font.render(&quot;Waiting...&quot;, 1, (0, 0, 0))
                  
          if p == 1:
              win.blit(text2, (100, 350))
              win.blit(text1, (400, 350))
          else:
              win.blit(text1, (100, 350))
              win.blit(text2, (400, 350))
                  
          for btn in btns:
              btn.draw(win)
              
      pygame.display.update()
          
          
          
  
      
      
      
  btns = [Button(&quot;Rock&quot;, 50, 500, (0, 0, 0)), Button(&quot;Scissors&quot;,  250, 500, (255, 0, 0)), Button(&quot;Paper&quot;, 450, 500, (0, 255, 0))]
  
  
  def main():
      run = True
      clock = pygame.time.Clock()
      n = Network()
      player = int(n.getP())
      print(&quot;You are player &quot;, player)
      
      while run:
          clock.tick(60)
          try:
              game = n.send2(&quot;get&quot;)
          except:
              run = False
              print(&quot;Couldn't get game&quot;)
              break
          
          if game.bothWent():
              redrawWindow(win, game, player)
              pygame.time.delay(500)
              try:
                  game = n.send2(&quot;reset&quot;)
              except:
                  run = False
                  print(&quot;Couldn't get game&quot;)
                  break
              
              font = pygame.font.SysFont(&quot;comicsans&quot;, 90)
              if (game.winner() == 1 and player == 1) or (game.winner() == 0 and player == 0):
                  text = font.render(&quot;You won!&quot;, 1, (255, 0, 0))
              elif game.winner() == -1:
                  text = font.render(&quot;Tie game!&quot;, 1, (255, 0, 0))
              else:
                  text = font.render(&quot;You lost&quot;, 1, (255, 0, 0))
                  
              win.blit(text, (width / 2 - text.get_width() / 2, height / 2 - text.get_height() / 2))
              pygame.display.update()
              pygame.time.delay(2000)
  
          for event in pygame.event.get():
              if event.type == pygame.QUIT:
                  run = False
                  pygame.quit()
              if event.type == pygame.MOUSEBUTTONDOWN:
                  pos = pygame.mouse.get_pos()
                  for btn in btns:
                      if btn.click(pos) and game.connected():
                          if player == 0:
                              if not game.p1_went:
                                  n.send2(btn.text)
                          else:
                              if not game.p2_went:
                                  n.send2(btn.text)
                                  
          redrawWindow(win, game, player)
                          
  def menuScreen():
      run = True
      clock = pygame.time.Clock()
      
      while run:
          clock.tick(60)
          win.fill((128, 128, 128))
          font = pygame.font.SysFont(&quot;comicsans&quot;, 60)
          text = font.render(&quot;Click to play!&quot;, 1, (255, 0, 0))
          win.blit(text, (100, 200))
          pygame.display.update()
          
          for event in pygame.event.get():
              if event.type == pygame.QUIT:
                  pygame.quit()
                  run = False
              if event.type == pygame.MOUSEBUTTONDOWN:
                  run = False
                  
      main()
      
  while True:
      menuScreen()
  </code></pre>