Как сделать простой многопоточный сервер сокетов в Python, который запоминает клиентов

Как мне сделать простой эхо-сервер Python, который запоминает клиентов и не создает новый сокет для каждого запроса? Должен быть в состоянии поддерживать одновременный доступ. Я хочу иметь возможность подключаться один раз и постоянно отправлять и получать данные, используя этот клиент или аналогичный:

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)

Т.е. на сервере, работающем через порт 50000, с помощью вышеуказанного клиента я хочу иметь возможность сделать это:

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

1 ответ

Решение

Вы можете использовать поток для каждого клиента, чтобы избежать блокировки client.recv() затем используйте основной поток только для прослушивания новых клиентов. Когда один из них подключается, основной поток создает новый поток, который просто слушает нового клиента и заканчивается, когда он не говорит в течение 60 секунд.

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

Тайм-аут клиентов после 60 секунд бездействия и должен повторно подключиться. Увидеть линию client.settimeout(60) в функции ThreadedServer.listen()

Другие вопросы по тегам