Multi-Thread-Multi-Client-Server in Python

Ich schreibe einen Multi-Threaded, Multi-Client-Server in Python. Mehrere Benutzer können sich mit telnet verbinden und grundsätzlich als Chat-Server verwenden. Ich bin in der Lage, mit zwei Klienten durch telnet zu verbinden, aber ich lauf in die zwei folgenden Probleme:

  1. Der erste Client, der eine Nachricht sendet, wird sofort getrennt.
  2. Der andere Client empfängt nicht die Nachricht, die vom ersten Client gesendet wird.

Server-Code:

import os import sys import socket import thread port = 1941 global message global lock global file def handler(connection): while 1: file = connection.makefile() file.flush() temp = file.readline() if temp == 'quit': break lock.acquire() message += temp lock.release() file.write(message) file.close() acceptor = socket.socket(socket.AF_INET, socket.SOCK_STREAM) acceptor.bind(('', port)) acceptor.listen(10) lock = thread.allocate_lock() while 1: connection, addr = acceptor.accept() thread.start_new_thread(handler, (connection,)) 

Ok, ich habe Unholysampler zugehört und jetzt habe ich das. Ich bin in der Lage, mit beiden Clients jetzt zu verbinden und Nachrichten zu schreiben, aber sie werden nicht gesendet / empfangen (ich kann nicht sagen, welches).

 import os import sys import socket import thread port = 1953 def handler(connection): global message global filelist filelist = [] file = connection.makefile() file.flush() filelist.append(file) message = '' while 1: i = 0 while i < (len(filelist)): filelist[i].flush() temp = filelist[i].readline() if temp == 'quit': break with lock: message += temp i = i + 1 file.close() global lock acceptor = socket.socket(socket.AF_INET, socket.SOCK_STREAM) acceptor.bind(('', port)) acceptor.listen(10) lock = thread.allocate_lock() while 1: connection, addr = acceptor.accept() thread.start_new_thread(handler, (connection,)) 

  • Python socket.error: [Errno 111] Verbindung abgelehnt
  • Wiederherstellung von zmq.error.ZMQError: Adresse bereits verwendet
  • Warum hat die Verbindung für ipv6 bei Python gescheitert?
  • Mehrere gleichzeitige Netzwerkverbindungen - Telnet Server, Python
  • Sudo Command mit Paramiko ausführen
  • C / Python Socket Leistung?
  • Senden einer Datei über TCP-Sockets in Python
  • Python BaseHTTPServer: Wie bekommst du es zu stoppen?
  • 3 Solutions collect form web for “Multi-Thread-Multi-Client-Server in Python”

    Es ist viel einfacher und besser, diese Art von Ding mit Twisted , die Sie können mehrere Clients gleichzeitig in einem einzigen Thread, sowie die Bereitstellung einer schöneren API zu implementieren.

    Hier ist, wie Sie einen Chat-Server mit Twisted (vollständiges Beispiel in chatserver.py ) schreiben:

     class MyChat(basic.LineReceiver): def connectionMade(self): print "Got new client!" self.factory.clients.append(self) def connectionLost(self, reason): print "Lost a client!" self.factory.clients.remove(self) def lineReceived(self, line): print "received", repr(line) for c in self.factory.clients: c.message(line) def message(self, message): self.transport.write(message + '\n') 

    Für jeden Benutzer wird ein MyChat Objekt erstellt und die Ereignisschleife ruft ihre Methoden für Start / Stop-Ereignisse auf und wann eine Zeile vom Client empfangen wird. In diesem Fall sendet man einfach jede Zeile, die sie an alle Clients im System erhält. Da es in einem einzigen Thread läuft, werden keine Sperren benötigt.

    Das ist nicht, wie du global . Wenn Sie eine Methode definieren, innerhalb des Methodenumfangs, verwenden Sie den globalen Befehl, um Verweise auf die Variable die höherwertige Variable zu machen.

     message = 1 def globalTest(): global message message += 1 print message print message globalTest() print message 

    Sie machen ein neues Dateiobjekt für die Verbindung jedes Mal, wenn Sie über die Schleife iterieren. Sie wollen das machen, bevor die Schleife beginnt, also machst du es nur einmal.

    Sie lesen und schreiben an das gleiche Dateiobjekt. Das bedeutet, es ist nur ein Echo-Server. Sie geben nie thread1 einen Verweis auf thread2's Datei. Der Versuch, eine globale Variable für die Socket-Datei verwenden wird nicht funktionieren, weil Sie nie wissen, welche Steckdose es tatsächlich zeigt auf. (Ausgabe # 2)

    Sie werden die Nachricht niemals initialisieren, also wird die message += temp UnboudLocalError einen UnboudLocalError besagt, dass es referenziert wird, bevor ein Wert zugewiesen wurde. (Wahrscheinlich die Ursache der Ausgabe # 1) Auch warum sind Sie Anhängen der Zeichenfolge an erster Stelle, das heißt, jedes Mal, wenn etwas gesendet wird, wird die gesamte Konversation ausgesendet.

    Auch nicht manuell erwerben und freigeben das Schloss, mit mit ist sauberer.

     with lock: message += temp 

    Ich denke, du musst an jedem beliebigen Anschluss anrufen. Das ist es in der Endlosschleife. while True: acceptor.listen(1) #...

    Python ist die beste Programmiersprache der Welt.