You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

65 lines
2.1 KiB

  1. #!/usr/bin/env python3.7
  2. import socket # socket, AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR
  3. import logging
  4. import threading
  5. import ClientConnection
  6. class Server(object):
  7. """
  8. A simple chat application server
  9. """
  10. clients = []
  11. soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  12. soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  13. def __init__(self, host: str, port: int, maxClients=64):
  14. self.host = host
  15. self.port = port
  16. self.soc.bind((host, port))
  17. self.maxClients = maxClients
  18. def run(self) -> None:
  19. """
  20. Start the server and start to listen for incoming connection
  21. """
  22. self.soc.listen(self.maxClients)
  23. logging.info('Start listening on {}:{} maximum {} clients'.format(
  24. self.host, self.port, self.maxClients))
  25. while True:
  26. conn, addr = self.soc.accept()
  27. client = ClientConnection.ClientConnection(self, conn, addr)
  28. msg = '{} has joined the chat.'.format(client.addr)
  29. self._announce(msg)
  30. self.clients.append(client)
  31. t = threading.Thread(target=client.serve)
  32. t.daemon = True
  33. t.start()
  34. def removeClient(self, client: ClientConnection.ClientConnection) -> None:
  35. """
  36. Remove client from this server list of connected clients
  37. """
  38. msg = '{} has left the chat.'.format(client.nameFormat())
  39. self.clients.remove(client)
  40. self._announce(msg)
  41. def _announce(self, announcement: str) -> None:
  42. """
  43. Send announcement from system to all connected clients
  44. """
  45. msg = '[system] {}'.format(announcement)
  46. logging.info(msg)
  47. for client in self.clients:
  48. client.send(msg)
  49. def sendToAll(self, sender: ClientConnection.ClientConnection, msg: str) -> None:
  50. """
  51. Broadcast message from one client to other clients
  52. """
  53. msg = '{} {}'.format(sender.nameFormat(), msg)
  54. logging.info(msg)
  55. for client in self.clients:
  56. if client != sender:
  57. client.send(msg)