简体   繁体   中英

Simple multithreaded Server Client Program

I have a multithreaded server and client programs for a simple game. Whenever a client force exits the game, I try to catch the exception with a try catch "except BrokenPipeError" and inform the other players. I also want to end the exited client thread; however, I take input such as this:

while True:
            client = serverSocket.accept()
            t = ServerThread(client)
            t.start()

I tried to use a threading event with stop() function; however, I believe I can not use a .join statement to exit the thread because of the way I take input. How should I end the force exited client. I know that multiprocessing library has a terminate function but I am also required to use the threading library. I tried os_exit(1) but I believe this command kills the entire process. What is the standard exit process for programs such as this?

First of all join() do nothing else but waits for thread to stop. Thread stops when it reaches end of threaded subroutine. For example

class ServerThread(threading.Thread):

   def __init__(self,client,name):
      super().__init__(self)
      self.client = client
      self.name = name

   def inform(self,msg):
      print("{}: got message {}".format( self.name, msg ))
      self.client[0].send(msg)

   def run(self):
      while True:
         try:
            self.client[0].recv(1024)
         except BrokenPipeError: #client exits
            # do stuff
            break # -> ends loop
      return # -> thread exits, join returns

If you want to inform other clients that someone leaves, i would make another monitoring thread

class Monitoring(threading.Thread):

   def __init__(self):
      super().__init__(self,daemon=True) # daemon means thread stops when main thread do
      self.clients=[]

   def add_client(self,client):
      self.clients.append(client)

   def inform_client_leaves(self,client_leaved):
      for client in self.clients:
         if client.is_alive():
            client.inform("Client '{}' leaves".format(client_leaved.name))

   def run(self):
      while True:
         for thread in list(self.threads):
            if not thread.is_alive(): # client exited
               self.threads.remove(thread)
               self.inform_client_exits(thread)
         time.sleep(1)

So the initial code would looks like

mon = Monitoring()
mon.start()
while True:
        client = serverSocket.accept()
        t = ServerThread(client,"Client1")
        t.start()
        mon.add_client(t)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM