2014-05-23 7 views
20

Wie mache ich einen einfachen Python-Echo-Server, der sich an Clients erinnert und keinen neuen Socket für jede Anfrage erstellt? Muss den gleichzeitigen Zugriff unterstützen können. Ich möchte in der Lage sein, einmal eine Verbindung herzustellen und kontinuierlich Daten zu senden und zu empfangen, die diesen Client oder ähnliches verwenden:Wie man einen einfachen Multithread-Socket-Server in Python erstellt, der sich an Clients erinnert

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. mit dem Server auf Port 50000 ausgeführt wird, die über Client verwenden möchte ich dies in der Lage sein zu tun:

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

Antwort

39

Sie einen Thread pro Client verwenden, kann die Sperrung client.recv() verwenden Sie dann den Haupt-Thread nur für das Hören für neue zu vermeiden Kunden. Wenn eine Verbindung hergestellt wird, erstellt der Haupt-Thread einen neuen Thread, der nur auf den neuen Client hört und endet, wenn 60 Sekunden lang nicht gesprochen wird.

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

Clients Timeout nach 60 Sekunden Inaktivität und muss erneut verbinden. Siehe die Zeile client.settimeout(60) in der Funktion ThreadedServer.listen()

+1

Ich fand diese interessante, kurze Frage ist die Zeile self.sock.listen (5) verantwortlich für die Anzahl der zulässigen Verbindungen? Also im Grunde kann ich 5 Kunden auf einmal akzeptieren, aber nicht mehr oder wofür sind die 5 gut? – Kev1n91

+1

@ Kev1n91 Die 5 ist das Rückstandsargument, das angibt, wie viele Verbindungen in die Warteschlange gestellt werden können und darauf warten, akzeptiert zu werden. Erklärt in der Dokumentation hier: https://docs.python.org/2/library/socket.html#socket.socket.listen – nettux443

+0

'Traceback (letzten Anruf zuletzt): Datei" E: /myProto/threadedserver.py ", Zeile 36, in ThreadedServer ('', port_num) .listen() Datei" E: /myProto/threadedserver.py ", Zeile 10, in __init__ self.sock.bind ((self.host, self .port)) TypeError: eine ganze Zahl ist erforderlich (bekam Typ str) ' –

Verwandte Themen