multiple clients using sockets

multiple clients using sockets

Postby metulburr » Mon Apr 07, 2014 1:41 am

There are quite a few examples on the net about a server/client, but not much regarding numerous clients. I am not sure how to accomodate for a second, or third client joining in?


server
Code: Select all
import socket
import threading


class Server:
   def __init__(self, host, port):
      self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      self.prompt = '>'
      self.buff = 1024
      self.host = host
      self.port = port
      self.sock.bind((self.host,self.port))
      self.sock.listen(5)
      self.conn, self.addr = self.sock.accept()
      threading.Thread(target=self.recv).start()
         
         
   def recv(self):
      while True:
         data = self.conn.recv(self.buff)
         if data:
            print(data)
            
   def send(self):
      user = input(self.prompt)
      self.conn.send(user.encode())
      
   def run(self):
      while True:
         self.send()
         
server = Server('', 8006)
server.run()
      


client
Code: Select all
import socket 
import threading

class Client:
   def __init__(self, host, port):
      self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      self.prompt = '>'
      self.buff = 1024
      self.host = host
      self.port = port
      self.sock.connect((self.host, self.port))
      threading.Thread(target=self.recv).start()

   def recv(self):
      while True:
         data = self.sock.recv(self.buff)
         if data:
            print(data)
            
   def send(self):
      user = input(self.prompt)
      self.sock.send(user.encode())
      
   def run(self):
      while True:
         self.send()


client = Client(socket.gethostname(), 8006)
client.run()
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1418
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: multiple clients using sockets

Postby metulburr » Mon Apr 07, 2014 7:56 am

ok i figured out how to make a couple connections. Each client can send data back o the server, and the server can send data back to the latest client, but not both clients. Kind of llike a chat room per se, is what i am trying to get out of it.


server:
Code: Select all
import socket
import threading

class Server:
   def __init__(self, host, port):
      self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      self.prompt = '>'
      self.buff = 1024
      self.host = host
      self.port = port
      self.sock.bind((self.host,self.port))
      self.max_conn = 5
      self.sock.listen(self.max_conn)
         
   def recv(self):
      self.conn, self.addr = self.sock.accept()
      while True:
         data = self.conn.recv(self.buff)
         if data:
            print(data)
            
   def send(self):
      while True:
         user = input(self.prompt)
         user = 'SERVER: ' + user
         self.conn.send(user.encode())
      
   def run(self):
      for i in range(self.max_conn):
         threading.Thread(target=self.recv).start()      
         threading.Thread(target=self.send).start()      
      #while True:
      #   self.send()
         
server = Server('', 8003)
server.run()
      


client:
Code: Select all
import socket 
import threading

class Client:
   def __init__(self, host, port):
      self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      self.prompt = '>'
      self.buff = 1024
      self.host = host
      self.port = port
      self.sock.connect((self.host, self.port))

   def recv(self):
      while True:
         data = self.sock.recv(self.buff)
         if data:
            print(data)
            
   def send(self):
      user = input(self.prompt)
      user = 'CLIENT: ' + user
      self.sock.send(user.encode())
      
   def run(self):
      threading.Thread(target=self.recv).start()
      while True:
         self.send()


client = Client(socket.gethostname(), 8003)
client.run()
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1418
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: multiple clients using sockets

Postby Crimson King » Mon Apr 07, 2014 4:16 pm

Hey metulburr, i found this lurking on SO


accept can continuously provide new client connections. However, note that it, and other socket calls are usually blocking. Therefore you have a few options at this point:

    Open new threads to handle clients, while the main thread goes back to accepting new clients
    As above but with processes, instead of threads
    Use asynchronous socket frameworks like Twisted, or a plethora of others



You could put all your clients on a list and then loop through it.

Have you read the docs on this 2 modules? Asyncore and Asynchat
User avatar
Crimson King
 
Posts: 85
Joined: Fri Mar 08, 2013 2:42 pm
Location: Buenos Aires, Argentina

Re: multiple clients using sockets

Postby metulburr » Thu Apr 10, 2014 12:14 am

Shouldnt it be possible with just threads and sockets? The clients recieve is on a separate thread, and the servers send is on a separate thread.

i am opening new threads for each client, while the main thread searches for more.
Code: Select all
   def run(self):
      for i in range(self.max_conn):
         conn, addr = self.sock.accept()
         self.clients.append(Client(conn, addr))
         threading.Thread(target=self.recv).start()
         threading.Thread(target=self.send).start()


I think i am quite lost...If you connect two clients it sometimes posts to one and sometimes post to the other.
http://asciinema.org/a/8791


server
Code: Select all
import socket
import threading

class Client:
   def __init__(self, conn, addr):
      self.addr = addr
      self.conn = conn

class Server:
   def __init__(self, host, port):
      self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      self.prompt = '>'
      self.buff = 1024
      self.host = host
      self.port = port
      self.sock.bind((self.host,self.port))
      self.max_conn = 5
      self.sock.listen(self.max_conn)
      self.clients = []
         
   def recv(self):
      while True:
         for client in self.clients:
            data = client.conn.recv(self.buff)
            if data:
               print('{} {}'.format(client.addr, data))
            
   def send(self):
      while True:
         for client in self.clients:
            user = input(self.prompt)
            user = 'SERVER: ' + user
            client.conn.send(user.encode())
      
   def run(self):
      for i in range(self.max_conn):
         conn, addr = self.sock.accept()
         self.clients.append(Client(conn, addr))
         threading.Thread(target=self.recv).start()
         threading.Thread(target=self.send).start()
         
server = Server('', 8009)
server.run()


I assumed that a possiblity was that the for loop was waiting for accept(), so i tried:
Code: Select all
import socket
import threading

class Client:
   def __init__(self, conn, addr):
      self.addr = addr
      self.conn = conn

class Server:
   def __init__(self, host, port):
      self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      self.prompt = '>'
      self.buff = 1024
      self.host = host
      self.port = port
      self.sock.bind((self.host,self.port))
      self.max_conn = 5
      self.sock.listen(self.max_conn)
      self.clients = []
         
   def recv(self):
      conn, addr = self.sock.accept()
      self.clients.append(Client(conn, addr))
      threading.Thread(target=self.send).start()
      while True:
         for client in self.clients:
            data = client.conn.recv(self.buff)
            if data:
               print('{} {}'.format(client.addr, data))
            
   def send(self):
      while True:
         for client in self.clients:
            user = input(self.prompt)
            user = 'SERVER: ' + user
            client.conn.send(user.encode())
      
   def run(self):
      for i in range(self.max_conn):
         #conn, addr = self.sock.accept()
         #self.clients.append(Client(conn, addr))
         threading.Thread(target=self.recv).start()
         #threading.Thread(target=self.send).start()
         
server = Server('', 8009)
server.run()

but i get the same results as the first one.

then i assumed that the problem might be that i need a lock so i tried:
Code: Select all
import socket
import threading

class Client:
   def __init__(self, conn, addr):
      self.addr = addr
      self.conn = conn

class Server:
   def __init__(self, host, port):
      self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      self.prompt = '>'
      self.buff = 1024
      self.host = host
      self.port = port
      self.sock.bind((self.host,self.port))
      self.max_conn = 5
      self.sock.listen(self.max_conn)
      self.clients = []
      self.lock = threading.Lock()
         
   def recv(self):
      while True:
         for client in self.clients:
            data = client.conn.recv(self.buff)
            if data:
               print('{} {}'.format(client.addr, data))
            
   def send(self):
      while True:
         for client in self.clients:
            user = input(self.prompt)
            user = 'SERVER: ' + user
            with self.lock:
               client.conn.send(user.encode())
            #self.lock.release()
      
   def run(self):
      for i in range(self.max_conn):
         conn, addr = self.sock.accept()
         self.clients.append(Client(conn, addr))
         threading.Thread(target=self.recv).start()
         threading.Thread(target=self.send).start()
         
server = Server('', 8009)
server.run()

but that was also the same result.

I was going to try multiprocessing instead, however, i am assuming that if i am having this problem with threads, that i will have the same problem with processes too.
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1418
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY


Return to Networking

Who is online

Users browsing this forum: No registered users and 1 guest