Cómo hacer un simple servidor de sockets multihilo en Python que recuerde clientes


¿Cómo puedo crear un servidor Python echo simple que recuerde clientes y no cree un nuevo socket para cada solicitud? Debe ser capaz de soportar el acceso concurrente. Quiero poder conectarme una vez y continuamente enviar y recibir datos usando este cliente o similar:

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)

Es decir, con el servidor corriendo en el puerto 50000, usando el cliente anterior quiero ser capaz de hacer esto:

me@mine:~$ client.py
Server hostname or ip? localhost
Server Port? 50000
message: testa
response: testa
message: testb
response: testb
message: testc
response: testc
Author: nettux443, 2014-05-23

1 answers

Puede usar un subproceso por cliente para evitar el bloqueo client.recv() luego use el subproceso principal solo para escuchar nuevos clientes. Cuando uno se conecta, el hilo principal crea un nuevo hilo que solo escucha al nuevo cliente y termina cuando no habla durante 60 segundos.

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

El tiempo de espera de los clientes después de 60 segundos de inactividad y deben volver a conectarse. Ver la línea client.settimeout(60) en la función ThreadedServer.listen()

 51
Author: nettux443,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-03 18:09:07