[IRC-Server]Mehr oder Weniger :D

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Benutzeravatar
ShuzZzle
User
Beiträge: 6
Registriert: Dienstag 20. November 2012, 21:55

Ich wollte folgende Idee umsetzen. Client a --> Verbindung zum server --> Server schickt nachricht an Client A Client B C D etc. Also so wie ein IRC-Chat system.
Dafür hab ich die Module Socket und Select benutzt. Geschrieben in 2.7.5

Hier mein Code für den Client:

Code: Alles auswählen

import socket
import select

ip = "hierwahrmalneipyow(ist ein root)"
nickname = "ShuzZzle"
dest = "ME"
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
sock.connect((ip, 2327))


while True:
	readable, writeable, exceptional = select.select([sock],[],[], 1)
	if readable:
		data = sock.recv(4096)
		nickname = data.split("#")[0]
		message = data.split("#")[1]
		print "[%s] %s" % (nickname,message)
	nachricht = raw_input("Nachricht: ") 
	sock.send(nickname + "#" + nachricht)
Problem Warten 1 Sekunde --> Keine Daten-->Senden Ausführen-->Bekommt keine Daten wenn "Senden ausgeführt wird" erst nachdem Senden. Wie mach ich das?
Hier ist noch mein Server-Code:

Code: Alles auswählen

import socket 
import select
##In Going Data#####
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
server.bind(("", 2327)) 
server.listen(1)
### End of In Going Data####


clients = []
Connections = {}

try: 
	while True: 
		lesen, schreiben, oob = select.select([server] + clients, 
												[], [])

		for sock in lesen: 
			if sock is server: 
				client, addr = server.accept() 
				clients.append(client)
				print "+++ Client %s verbunden" % addr[0]
			else:
				nachricht = sock.recv(1024)
				ip = sock.getpeername()[0]
				if nachricht:
					Nickname = nachricht.split("#")[0]
					#destination = nachricht.split("#")[1]
					reply = Nickname + "#" + nachricht.split("#")[1]
					print "[%s] %s" % (Nickname, nachricht.split("#")[1])
					try:
						for irchat in clients:
							irchat.send(reply)
							print "Data[%s] Sender(%s)" % (reply,irchat)
					except:
						print "+++ Verbindung zu %s beendet(Err2)" % ip
						sock.close()
						clients.remove(sock)
				else:
					print "+++ Verbindung zu %s beendet" % ip 
					sock.close() 
					clients.remove(sock) 
finally: 
	for c in clients: 
		c.close() 
	server.close()
P.s. Gibt es irgendwelche Seiten wo man das gut dokumentiert nachlesen kann?
MfG ShuzZzle
BlackJack

@ShuzZzle: Dein Client hat drei Probleme: 1. Ein `recv()` garantiert weder, dass die gesamte Nachricht gelesen wird, noch das es nur *eine* Nachricht ist, die da gelesen wird. TCP ist ein Datenstrom und ein `recv()` liest einen nahezu beliebigen Ausschnitt davon. Zumindest muss ein korrektes Programm so geschrieben sein, dass es davon ausgeht.

2. `raw_input()` blockiert solange bis der Benutzer etwas geschrieben und mit Enter abgeschlossen hat. So lange kann das Programm nichts anderes machen, also auch keine Nachrichten empfangen.

3. Es wird nicht berücksichtigt, dass die Nachricht selbst auch '#' enthalten kann. An der Stelle ist es übrigens auch ungünstig die `split()`-Operation zweimal durchzuführen, obwohl klar ist, dass beide Male das gleiche Ergebnis dabei herauskommen muss.
Benutzeravatar
ShuzZzle
User
Beiträge: 6
Registriert: Dienstag 20. November 2012, 21:55

Danke Schonmal dafür. Nur wie schaff ich das z.B. sowas

Code: Alles auswählen

def FetchData():
	while True:
		readable, writeable, exceptional = select.select([sock],[],[], 1)
		if readable:
			data = sock.recv(4096)
			nickname = data.split("#")[0]
			message = data.split("#")[1]
			print "[%s] %s" % (nickname,message)
Im Hintergrund arbeitet? und sich ständig aufruft? Sodass es nicht von inputs etc blockiert wird

Edit: Habs gelöst mit dem Threading modul Danke nochmal ;)
MfG ShuzZzle
BlackJack

@ShuzZzle: Das kann man mit dem `threading`-Modul machen, *dann* würde ich aber `select` weglassen, das macht das hier nur unnötig kompliziert.

Die Punkte 1. und 3. sind damit jetzt aber noch nicht gelöst.
SemperPython

@ShuzZzle

Kannst du mir bitte den neuen Code schicken mit dem threading-Modul.
SemperPython

@ShuZzle
Würdest du mir bitte den neuen Code schicken?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

@SemperPython: Wenn der OP schon so lange darauf nicht reagiert hat, besteht eher wenig Hoffnung, dass er das noch tut. Du solltest das am besten per PM versuchen oder gucken, ob er anderweitige Kontaktdaten hier im Forum hinterlegt hat, die Du nutzen kannst!
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten