Multi-Client Chat - Server 100% Core Last

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Scriptonator
User
Beiträge: 14
Registriert: Mittwoch 23. Februar 2011, 18:16

Hallo erstmal,
hab mich gerade hier angemeldet, um von euch etwas Hilfe zu bekommen.
Und zwar habe ich vor kurzem mit Python angefangen, und finde es ganz toll und nützlich.

1. Ich hab mir die Aufgabe gestellt, einen kleinen LAN-Chat zu machen.
Dieser funktioniert auch schon fast gut, nur das Disconnecten der Clients geht nicht, da stützt der Server ab. Ich habe da auch noch keine Kontrollstrukturen eingebaut, welche try except Sachen brauche ich da?

2. Bei meiner server.py ist in irgendeiner while-Schleife ein fehler, denn diese Lastet einem meiner 4 Kerne zu 100 % aus.

Könnt ihr mir etwas helfen ?

Client:

Code: Alles auswählen


import socket
import thread
import sys

ip = raw_input("IP-Adresse: ") 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.connect((ip, 50000))

def recv_nachricht():
    while True:
       antwort = s.recv(1024) 
       text= antwort
       print text
       
def send_nachricht():
    while True:
        nachricht = raw_input("") 
        s.send(nachricht) 

thread.start_new_thread(send_nachricht, ())
thread.start_new_thread(recv_nachricht, ())

while True:
    pass
Server:

Code: Alles auswählen

import thread
import socket
import time

print "[*]Started Thread_Server"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.bind(("", 50000)) 
s.listen(1)
clientlist=[]

def recvdata(client):
    clientlist.append(client)
    while True:
        data=client.recv(1024)
        if not data:
            client.close()
        else:
            for cl in clientlist:
                if cl == client or not cl:
                    continue
                cl.send(data)
        
def check_new_client():
    while True:
        client, addr = s.accept() 
        if not client :
            pass
        else :
            thread.start_new_thread(recvdata, (client,))
        
thread.start_new_thread(check_new_client, ())
while True:
    pass

Ich werde vielleicht gleich noch einige Kommentare schreiben, aber erstmal gibts essen.

Gruß
Scriptonator
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Naja, ein

Code: Alles auswählen

while True:
    pass
    # bzw. Code, der "durchläuft"
Ist auch eine denkbar schlechte Idee ;-)

Zudem nutzt man eigentlich eher das threading-Modul, welches höher abstrahiert als das thread-modul.

Als letztes: Wenn Du eher am Funktionieren interessiert bist, als an dem low-level socket Kram, dann guck Dir doch mal XML-RPC an. Das macht doch vieles einfacher bezüglich einer Kommunikation.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Scriptonator
User
Beiträge: 14
Registriert: Mittwoch 23. Februar 2011, 18:16

Das mit dem

Code: Alles auswählen

while True:
 pass
habe ich gelesen, das man das braucht, damit die Threads weiterlaufen, weil wenn das Programm zu Ende ist, werden auch die Threads beendet.

Auch hatte ichg gelesen, das das thread-modul funktionen übernimmt, das threading-modul hingegen nur Klassen.?

XML-RPC werde ich mir mal anschauen, würde es trotzdem aber erstmal so versuchen zu realisieren.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Scriptonator hat geschrieben:Das mit dem

Code: Alles auswählen

while True:
 pass
habe ich gelesen, das man das braucht, damit die Threads weiterlaufen, weil wenn das Programm zu Ende ist, werden auch die Threads beendet.
Wo hast Du denn das gelesen? Naja, man muss schon sicherstellen, dass das Programm so lange in einer Schleife bleibt, wie notwendig. Aber das sollte man immer so handhaben, dass die Schleife nur dann weiter läuft, sobald Daten eintreffen o.ä..
Ich bezog mich damit auch auf die Funktion check_new_client(). Da passiert das sicherlich auch idR.
Auch hatte ichg gelesen, das das thread-modul funktionen übernimmt, das threading-modul hingegen nur Klassen.?
Wo hast Du denn das gelesen? Und man kann threading.Thread ja mittels target-Parameter ein ausführbares Objekt übergeben, wie eben eine Funktion.
XML-RPC werde ich mir mal anschauen, würde es trotzdem aber erstmal so versuchen zu realisieren.
War ja auch nur ein Tipp :-)

Generell hast Du nach meinem Geschmack zu viel Code auf Modulebene. Du solltest das alles in Funktionen verpacken (teilweise wohl in eine main()-Funktion) und dann so einbinden:

Code: Alles auswählen

if __name__ == "__main__":
    main()
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Scriptonator
User
Beiträge: 14
Registriert: Mittwoch 23. Februar 2011, 18:16

Gut, dann werde ich es mir mal anschauen :)
Danke.

Weitere Ratschläge sind weiterhin gerne gesehen ;)
Benutzeravatar
name
User
Beiträge: 254
Registriert: Dienstag 5. September 2006, 16:35
Wohnort: Wien
Kontaktdaten:

Bitte, bitte; tu das nicht. Schau dir mal die gängigen Netzwerkbibliotheken an, weil man üblicherweise den select, poll, epoll oder kqueue syscall nimmt um event based Networking zu machen. Danke.
Ohloh | Mein Blog | Jabber: segfaulthunter@swissjabber.eu | asynchia – asynchrone Netzwerkbibliothek

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
Antworten