Client-Server Chat

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
r00t
User
Beiträge: 7
Registriert: Samstag 18. April 2009, 12:58

Hi hier hab i mal nen kleines Programm geschrieben das einen Chat zwischen einem Teilnehmer(Server) und einem anderen (Client) gewährleisten soll. Ich habe versucht dass ganze mit Threads so zu machen, dass man nicht immer auf rückmeldung des anderen warten muss. Allerdings kommt im Test nur die Nachricht vom Client zum Server an und nicht vom Server zum Client!
Server-Code

Code: Alles auswählen

import socket
import threading
import Queue
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(("",50000))
s.listen(1)

class Chatserverempfangen(threading.Thread):						
			
	def __init__(self):
		threading.Thread.__init__(self)
	def run(self):
		try:
			while True:
		
				print "Warte auf Teilnehmer"
				komm,addr = s.accept()					
				print komm
				print addr
				while True:
					data=komm.recv(1024)
					if not data:					
						print "Teilnehmer hat sich abgemeldet"
						komm.close()
						break
					print "[%s] %s" %(addr[0],data)
					
		finally:
			s.close()

class Chatserversenden(threading.Thread):						
	Briefkasten=Queue.Queue()							
	def __init__(self):
		threading.Thread.__init__(self)
	def run(self):
		while True:
			komm,addr=s.accept()
			
			while True:
				
				nachricht=Chatserversenden.Briefkasten.get()			
				komm.send(nachricht)
				Chatserversenden.Briefkasten.task_done()			



											
thread1=Chatserverempfangen()
thread1.start()			
thread2=Chatserversenden()
thread2.setDaemon(True)
thread2.start()



while True:										
	eingabe=raw_input("> ")						
	if eingabe=="exit":
		break
	else:
		Chatserversenden.Briefkasten.put(eingabe)				


Chatserversenden.Briefkasten.join()							
thread1.join()					

					
und hier der code für den client

Code: Alles auswählen

import socket
import threading
import Queue
ip=raw_input('Geben Sie IP ein: ')
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((ip,50000))
class Chatserverempfangen(threading.Thread):						
			
	def __init__(self):
		threading.Thread.__init__(self)
	def run(self):
		antwort=s.recv(1024)
		print "[Server]"+antwort
class Chatserversenden(threading.Thread):						
	Briefkasten=Queue.Queue()							
	def __init__(self):
		threading.Thread.__init__(self)
	def run(self):
		
				
		nachricht=Chatserversenden.Briefkasten.get()			
		s.send(nachricht)
		Chatserversenden.Briefkasten.task_done()			




thread1=Chatserverempfangen()
thread1.start()			
thread2=Chatserversenden()
thread2.setDaemon(True)
thread2.start()



while True:										
	eingabe=raw_input("> ")						
	if eingabe=="exit":
		break
	else:
		Chatserversenden.Briefkasten.put(eingabe)				


Chatserversenden.Briefkasten.join()							
thread1.join()		
								
Was haltet ihr davon? ich weis ist noch sehr einfach! Und woran liegt es dass der Client nicht die Nachricht vom Server bekommt?
BlackJack

@r00t: `Briefkasten` sollte kein Klassenattribut sein, sondern eines auf den Exemplaren. Und zumindest die Klassen/Objekte, die keine Attribute haben und in denen in der `__init__()` nur `Tread` initialisiert wird, würde ich nicht in Klassen stecken. Man kann einem `Thread` bei der Erstellung auch einfach eine Funktion mitgeben, die ausgeführt werden soll.

Namen sollte man nicht einfach durchnummerieren. Bei `thread1` und `thread2` wird aus dem Namen gar nicht deutlich was diese Objekte in dem Programm für eine Bedeutung haben.

Falsch ist auf jeden Fall das `s.accept()` in `Chatversenden.run()` beim Server. Das bedeutet ja, dass bei dem Socket auf eine *eingehende* Verbindung vom *Serversocket* gewartet werden soll, was so ja gar nicht stimmt. Man möchte dort ja an den Socket senden, der irgendwann vorher einmal von diesem Serversocket bei `accept()` zurückgegeben wurde und die Verbindung zu einem Chatclient darstellt. Womit es vielleicht keine gute Idee ist, das versenden und empfangen hier auf zwei verschiedene Klassen zu verteilen, weil die beiden `run`-Funktionen ja auf gemeinsamen Zustand zugreifen müssen.
r00t
User
Beiträge: 7
Registriert: Samstag 18. April 2009, 12:58

@BlackJack
und wie mache ich des dann dass man nicht immer auf ne antwort vom server warten muss bis man wieder schreiben kann? weil des is ja grad des problem
Antworten