title: Multiclient server in Python - how to broadcast?
body: <p>I found online a simple multiclient echo server in Python using threads:</p>
  
  <pre><code>#!/usr/bin/env python
  import socket
  import sys
  import threading
  
  class Client(threading.Thread):
      def __init__(self, ip, port, connection):
          threading.Thread.__init__(self)
          self.connection = connection
          self.ip = ip
          self.port = port
  
      def run(self):
  
          data = self.connection.recv(1024)
          if data :
              self.connection.sendall(data)
          else :
              self.connection.close()
  
  class Server:
      def __init__(self, ip, port):
          self.ip = ip
          self.port = port
          self.address = (self.ip, self.port)
          self.server = None
          self.clients = []
  
      def open_socket(self):
          try:
              self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
              self.server.bind(self.address)
          except socket.error, e:
              if self.server:
                  self.server.close()
              sys.exit(1)
  
      def run(self):
          self.open_socket()
          self.server.listen(5)
  
          while True :
              connection, (ip, port) = self.server.accept()
  
              c = Client(ip, port, connection)
              c.start()
  
              self.clients.append(c)
  
          self.server.close()
  
  if __name__ == '__main__':
      s = Server('127.0.0.1', 6666)
      s.run()
  </code></pre>
  
  <p>And I wrote a client:</p>
  
  <pre><code>import socket
  import sys
  
  port = 6666
  size = 1024
  s = None
  try:
      s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      host = socket.gethostname()
      s.connect(('127.0.0.1', port))
  except socket.error, (value, message):
      if s:
          s.close()
      print "Could not open socket: " + message
      sys.exit(1)
  data = raw_input('&gt; ')
  s.sendall(data)
  data = s.recv(size)
  print "Server sent: %s " % data
  s.close()
  </code></pre>
  
  <p>Everything works great but I wonder how could I add to the server the functionality of broadcast to be able to echo back the message to all connected clients? Or be able to send a message to a specific client? </p>
  
  <p>I have all clients in server's class, but I do not know how to (and where in the server's code, in <code>Client</code> class or <code>Server</code> class place the code to broadcast and send private messages? Thank you. </p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>New server:</p>
  
  <pre><code>#!/usr/bin/env python
  import socket
  import sys
  import threading
  
  class Client(threading.Thread):
      def __init__(self, ip, port, connection):
          threading.Thread.__init__(self)
          self.connection = connection
          self.ip = ip
          self.port = port
  
      def run(self):
          while True:
              data = self.connection.recv(1024)
              if data :
                  self.connection.sendall(data)
              else :
                  break
          self.connection.close()
  
  
  class Server:
      def __init__(self, ip, port):
          self.ip = ip
          self.port = port
          self.address = (self.ip, self.port)
          self.server = None
          self.clients = []
  
      def send_to_all_clients(self, msg):
          for client in self.clients :
              client.connection.send(msg)
  
      def send_to_client(self, ip, port, msg):
          for client in self.clients :
              if client.ip == ip and client.port == port :
                  client.connection.send(msg)
  
      def open_socket(self):
          try:
              self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
              self.server.bind(self.address)
          except socket.error, e:
              if self.server:
                  self.server.close()
              sys.exit(1)
  
      def run(self):
          self.open_socket()
          self.server.listen(5)
  
          while True :
              connection, (ip, port) = self.server.accept()
  
              c = Client(ip, port, connection)
              c.start()
  
              self.clients.append(c)
  
          self.server.close()
  
  if __name__ == '__main__':
      s = Server('127.0.0.1', 6666)
      s.run()
  </code></pre>
  
  <p>New client:</p>
  
  <pre><code>import socket
  import sys
  
  port = 6666
  size = 1024
  s = None
  try:
      s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      host = socket.gethostname()
      s.connect(('127.0.0.1', port))
  except socket.error, (value, message):
      if s:
          s.close()
      print "Could not open socket: " + message
      sys.exit(1)
  
  while True:
      data = raw_input('&gt; ')
      s.sendall(data)
      data = s.recv(size)
      print "Server sent: %s " % data
  s.close()
  </code></pre>