web-dev-qa-db-fra.com

Comment créer un serveur de socket multithread simple dans Python qui se souvient des clients

Comment créer un simple Python qui se souvient des clients et ne crée pas de nouveau socket pour chaque demande? Doit pouvoir prendre en charge l'accès simultané. Je souhaite pouvoir me connecter une fois et envoyer et recevoir en continu des données à l'aide de ce client ou d'un autre similaire:

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)

C'est à dire. avec le serveur fonctionnant sur le port 50000, en utilisant le client ci-dessus, je veux pouvoir le faire:

me@mine:~$ client.py
Server hostname or ip? localhost
Server Port? 50000
message: testa
response: testa
message: testb
response: testb
message: testc
response: testc
33
nettux

Vous pouvez utiliser un thread par client pour éviter le blocage client.recv(), puis utilisez le thread principal uniquement pour écouter de nouveaux clients. Lorsqu’une personne se connecte, le thread principal crée un nouveau thread qui écoute simplement le nouveau client et se termine s’il ne parle pas pendant 60 secondes.

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()

Les clients expirent après 60 secondes d'inactivité et doivent se reconnecter. Voir la ligne client.settimeout(60) dans la fonction ThreadedServer.listen()

69
nettux