2014-05-23 7 views
20

Come posso creare un semplice server echo Python che ricordi i client e non crei un nuovo socket per ogni richiesta? Deve essere in grado di supportare l'accesso simultaneo. Voglio essere in grado di connettermi una volta e inviare e ricevere continuamente dati utilizzando questo client o simili:Come creare un semplice server socket multithread in Python che ricordi i client

import socket 

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
host = raw_input("Server hostname or ip? ") 
port = input("Server port? ") 
sock.connect((host,port)) 
while True: 
    data = raw_input("message: ") 
    sock.send(data) 
    print "response: ", sock.recv(1024) 

I.e. con il server in esecuzione sulla porta 50000, utilizzando il client di cui sopra che voglio essere in grado di fare questo:

[email protected]:~$ client.py 
Server hostname or ip? localhost 
Server Port? 50000 
message: testa 
response: testa 
message: testb 
response: testb 
message: testc 
response: testc 

risposta

39

È possibile utilizzare un thread per ogni cliente di evitare il blocco client.recv() quindi utilizzare il thread principale solo per l'ascolto per il nuovo clienti. Quando ci si connette, il thread principale crea un nuovo thread che ascolta solo il nuovo client e termina quando non parla per 60 secondi.

import socket 
import threading 

class ThreadedServer(object): 
    def __init__(self, host, port): 
     self.host = host 
     self.port = port 
     self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
     self.sock.bind((self.host, self.port)) 

    def listen(self): 
     self.sock.listen(5) 
     while True: 
      client, address = self.sock.accept() 
      client.settimeout(60) 
      threading.Thread(target = self.listenToClient,args = (client,address)).start() 

    def listenToClient(self, client, address): 
     size = 1024 
     while True: 
      try: 
       data = client.recv(size) 
       if data: 
        # Set the response to echo back the recieved data 
        response = data 
        client.send(response) 
       else: 
        raise error('Client disconnected') 
      except: 
       client.close() 
       return False 

if __name__ == "__main__": 
    while True: 
     port_num = input("Port? ") 
     try: 
      port_num = int(port_num) 
      break 
     except ValueError: 
      pass 

    ThreadedServer('',port_num).listen() 

I client scadono dopo 60 secondi di inattività e devono riconnettersi. Vedere la riga client.settimeout(60) nella funzione ThreadedServer.listen()

+1

Ho trovato questa interessante, breve domanda è la linea self.sock.listen (5) responsabile della quantità di connessioni consentite? Quindi in pratica posso accettare 5 client contemporaneamente ma non di più o a cosa serve il 5? – Kev1n91

+1

@ Kev1n91 Il 5 è l'argomento del backlog che specifica quante connessioni possono essere accodate in attesa di essere accettate. Spiegato nei documenti qui: https://docs.python.org/2/library/socket.html#socket.socket.listen – nettux443

+0

'Traceback (ultima chiamata ultima): File" E: /myProto/threadedserver.py ", riga 36, ​​in ThreadedServer ('', port_num) .listen() File" E: /myProto/threadedserver.py ", riga 10, in __init__ self.sock.bind ((self.host, self .port)) TipoErrore: è richiesto un numero intero (ottenuto il tipo str) ' –