socket abgebrochen

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
cime
User
Beiträge: 152
Registriert: Dienstag 24. Mai 2005, 15:49

Hallöche,

ich hab da so ein kleines prob ... wie kann man herausbekommen, ob ein socket abgebrochen wurde, damit meine ich .... zwei sockets wurden verbunden und dann schließt der ein einfach so das Programm ... wie kann ich herausbekommen, ob das so ist ... gibt es vielleicht eine methode, der ich eine Funktion mitsamt parameter übergeben kann, die dann ausgeführt wird???

mfg cime
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Müsste socket dann nicht eine Exception werfen? Zumindest, wenn du das nächste mal einSoecketObj.send() versuchst, sollte eine Exception kommen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
cime
User
Beiträge: 152
Registriert: Dienstag 24. Mai 2005, 15:49

Leonidas hat geschrieben: Müsste socket dann nicht eine Exception werfen?


nö, tuts nich ...
Leonidas hat geschrieben: Zumindest, wenn du das nächste mal einSoecketObj.send() versuchst, sollte eine Exception kommen.
ja, aber ich hab gehofft, es ginge noch irgendwie einfacher ....

hier mal der Quelltext ...

Code: Alles auswählen

#server.py


from thread import start_new

from socket impmort socket

PASSWORD='#\x11##\xa3aai#\x11#\xa3aai\x11\x11\x11\x11\xe1[[3##\x11#\xe1\xcbai#\x11#\xa3aai\xa3\xa3\xe1\xe1\xa3\xe1\xe1\xa3aa[\xcba\xe1\xcb#aa[aa\xe1\xcb#ii3ii\xa3##'
#start now
ADMINPW='\xcbi\x99\xa3i\x99\xcb##\xcb\x99[\xe1\x99\xc9\x1133i\x993\xe1#\x11\x99a\xcb\x99[3\xe13C\xc9\x11\x11\xa3\xe1\xe1\xe1\xa3\xe1\xe1\xe1\xe1i\x99#3\xa33\x99aa\x99\xc9\x11C\xe13\xc9\x11\x11\xcb\x11\x99\xc9\xe1\x99\xc933#3a\x11\xe1a\x113\xcb#3\xcb\x11\xe1a\x113\xcb'
#wird schon

def crypt2(pwd):
	new=''
	for a in pwd:
		z=ord(a)
		for b in pwd:
			if b!=a:
				y=ord(b)
				n=int((y*z)/float(y+z))
				new+=chr((3**n)%256)
	return new

def crypt(pwd):
	new=''
	old=1
	for a in pwd:
		z=ord(a)
		n=int((old*z)/float(old+z))
		old=z
		new+=chr((3**n)%256)
	return new

class user_object:
    def __init__(self,ip,sock,idn):
        self.sock=sock
        self.name=None
        self.ip=ip
        self.idn=idn
        self.logged_in=False
        self.admin=False
        self.online=True
    def login(self,name,pwd):
        if crypt2(pwd)==PASSWORD:
            self.name=name
            self.logged_in=True
            return True
        return False

class user_book:
    def __init__(self):
        self.idn=0
        self.userlist=[]
    def get_user(self,name=None,ip=None,idn=None,sock=None):
        for user in self.userlist:
            if not idn is None and idn==user.idn:
                return user
            elif not ip is None and ip==user.ip:
                return user
            elif not name is None and name==user.name:
                return user
            elif not sock is None and name==user.sock:
                return user
        return None
    def add_user(self,ip,sock):
        idn=self.idn
        new=user_object(ip,sock,idn)
        self.idn+=1
        self.userlist.append(new)
        return new
    def del_user(self,name=None,ip=None,idn=None):
        self.userlist.remove(self.get_user(name=name,ip=ip,idn=idn))
    def login(self,user,name,pwd):
        if name in [i.name for i in self.userlist]:#name is in use
            user.sock.send('name already in use\r\n')
            return False
        else:#name is not in use
            return user.login(name,pwd)

class server:

    
    def __init__(self,port):
        self.allcommands={
            '/quit':self.close_connection
            }
        self.sock=socket()
        self.sock.bind(('',port))
        self.sock.listen(1)
        self.all_user=user_book()
        start_new(self.get_new_user,())
        a=raw_input('Konfiguration?')
        
    def get_new_user(self):
        sock,(ip,nport)=self.sock.accept()
        start_new(self.get_new_user,())
        user=self.all_user.add_user(ip,sock)
        self.work_with(user)
    def work_with(self,user):
        #start login loop
        user.sock.send('authorization required\r\n')
        text=self.get_text(user.sock)[:-2]
        if text is None:
            all_user.del_user(user)
            return #connection collapsed
        if self.check_command(text):
            logged_in=self.all_user.login(user,*text.split(None,2)[1:3])
        else:
            logged_in=False
            user.sock.send('unknown command\r\n')
        while not logged_in:
            user.sock.send('authorization failed\r\n')
            text=self.get_text(user.sock)[:-2]
            if text is None:
                all_user.del_user(user) 
                return #connection collapsed
            if self.check_command(text):
                logged_in=self.all_user.login(user,*text.split(None,2)[1:3])
            else:
                user.sock.send('unknown command\r\n')
        user.sock.send('authorization succeeded\r\n')
        #end login loop
        #start chat loop
        while user.online:
            text=self.get_text(user.sock)
            if text is None:
                all_user.del_user(user)
                user.online=False
                return #connection collapsed
            elif text.startswith('/'):
                command=text.split(None,1)[0]
                if command in self.allcommands.keys():
                    self.allcommands[command](text,user)
                else:
                    user.sock.send('unknown command\r\n')
            else:
                self.send_to_all(user.name,text,'%s : %s')
        #end chat loop
    def close_connection(self,string,user):
        self.all_user.del_user(idn=user.idn)
        user.online=False
    def send_to_all(self,name,text,format):
        text=format%(name,text)
        for user in self.all_user.userlist:
            user.sock.send(text)
    def check_command(self,line):
        if line.startswith('/login'):
            return line.split(None,2).__len__()==3
    def get_text(self,sock):
        text=sock.recv(1024)
        while not text:
            text=sock.recv(1024)
        return text
    def __del__(self):
        pass

if __name__=='__main__':
    a=server(8001)
meine einzige Idee wäre jetzt, das die Methode send vom socket-objekt so umzuschreiben, damit dieser immer True oder False zurückgibt ...

PS1: ich möchte noch ein config-programm dazu erzeugen, dass auf dem selben rechner laufen soll, wie könnte ich die beiden Rechner miteinander kommunizieren lassen????
PS2: das soll übrigens ein chatserver sein, der auf dem Port 8001 ansprechbar ist (hab noch keinen client ... daher mit putty (o.Ä.) per Raw (Telnet klappt auch) anmelden .... (/login [name] start now)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

cime hat geschrieben:meine einzige Idee wäre jetzt, das die Methode send vom socket-objekt so umzuschreiben, damit dieser immer True oder False zurückgibt ...
Das ist ja kein Problem, etwa so (ungetestet):

Code: Alles auswählen

import socket

class VerifiedSocket(socket.socket):
    def send(self, *args, **kwargs):
        try:
            socket.socket.send(self, *args, **kwargs)
            return True
        except:
            return False
cime hat geschrieben:PS1: ich möchte noch ein config-programm dazu erzeugen, dass auf dem selben rechner laufen soll, wie könnte ich die beiden Rechner miteinander kommunizieren lassen????
Ich würde es mit XML-RPC versuchen, siehe Kategorie IPC+Python im Comprehensive Bookmark Archive.
cime hat geschrieben:PS2: das soll übrigens ein chatserver sein, der auf dem Port 8001 ansprechbar ist (hab noch keinen client ... daher mit putty (o.Ä.) per Raw (Telnet klappt auch) anmelden .... (/login [name] start now)
Für einen Chatserver.. sieh dir doch Pyro an, das hat bei den Beispielprogrammen einen Chatserver dabei.
Zuletzt geändert von Leonidas am Donnerstag 17. November 2005, 15:50, insgesamt 1-mal geändert.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

cime hat geschrieben: def check_command(self,line):
if line.startswith('/login'):
return line.split(None,2).__len__()==3[/python]
Bitte `len()` benutzen.

Code: Alles auswählen

    def get_text(self,sock):
        text=sock.recv(1024)
        while not text:
            text=sock.recv(1024)
        return text
    def __del__(self):
        pass
Frage zu `get_text()`: Ich dachte immer `recv()` blockiert so lange bis mindestens ein Byte gelesen werden konnte!? Dann ist die Schleife überflüssig.

Und das definieren von `__del__()` sorgt dafür, das die Objekte nicht mehr einfach so vom Garbage Collector abgeräumt werden.
meine einzige Idee wäre jetzt, das die Methode send vom socket-objekt so umzuschreiben, damit dieser immer True oder False zurückgibt ...
Fehlercodes zu zurück zu geben ist sehr "unpythonic". Ich würde Exceptions benutzen.
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

BlackJack hat geschrieben:Frage zu `get_text()`: Ich dachte immer `recv()` blockiert so lange bis mindestens ein Byte gelesen werden konnte!? Dann ist die Schleife überflüssig.
Wäre auch irgendwie logisch. Weil nach welchem System sollte er sonst Daten empfangen? Alle X ms?
TUFKAB – the user formerly known as blackbird
cime
User
Beiträge: 152
Registriert: Dienstag 24. Mai 2005, 15:49

--> bitte löschen, hab hier nen fehler gemacht ...
Zuletzt geändert von cime am Freitag 18. November 2005, 18:20, insgesamt 1-mal geändert.
cime
User
Beiträge: 152
Registriert: Dienstag 24. Mai 2005, 15:49

--> bitte löschen, hab hier nen fehler gemacht ...

(bin zwei mal auf absenden gekommen, anstatt auf vorschau ...)
Zuletzt geändert von cime am Freitag 18. November 2005, 18:21, insgesamt 1-mal geändert.
cime
User
Beiträge: 152
Registriert: Dienstag 24. Mai 2005, 15:49

erstmal danke an alle ... ich habs inzwischen erweitert ... (Pyro hab ich mir noch nicht aqngeschaut ... mach ich aber noch)
BlackJack hat geschrieben: Frage zu `get_text()`: Ich dachte immer `recv()` blockiert so lange bis mindestens ein Byte gelesen werden konnte!? Dann ist die Schleife überflüssig.

Und das definieren von `__del__()` sorgt dafür, das die Objekte nicht mehr einfach so vom Garbage Collector abgeräumt werden.
schau sie dir jetzt nochma an ... das hat ich eh vor, war aber bis dato zu faul *g*
BlackJack hat geschrieben: Fehlercodes zu zurück zu geben ist sehr "unpythonic". Ich würde Exceptions benutzen.
ich arbeite doch mit exceptions, ich habe nur keine lust ungefähr 20-mal try und except zu scheriben (ma abgesehen von der unübersichtlichkeit des codes)... von daher schreib ich das nur einmal und gebs in einer variable (user.online) zurück ...

... das mit dem verifiedsocket hat irgendwie nicht funktioniert (er wollte einfach nicht in die neue send methode gehen (hat immer die alte verwendet..)

hier noch der quelltext ...

Code: Alles auswählen

#server.py


from thread import start_new

from socket import socket

PASSWORD='#\x11##\xa3aai#\x11#\xa3aai\x11\x11\x11\x11\xe1[[3##\x11#\xe1\xcbai#\x11#\xa3aai\xa3\xa3\xe1\xe1\xa3\xe1\xe1\xa3aa[\xcba\xe1\xcb#aa[aa\xe1\xcb#ii3ii\xa3##'
#start now
ADMINPW='\xcbi\x99\xa3i\x99\xcb##\xcb\x99[\xe1\x99\xc9\x1133i\x993\xe1#\x11\x99a\xcb\x99[3\xe13C\xc9\x11\x11\xa3\xe1\xe1\xe1\xa3\xe1\xe1\xe1\xe1i\x99#3\xa33\x99aa\x99\xc9\x11C\xe13\xc9\x11\x11\xcb\x11\x99\xc9\xe1\x99\xc933#3a\x11\xe1a\x113\xcb#3\xcb\x11\xe1a\x113\xcb'
#wird schon

# Line terminators (we always output CRLF, but accept any of CRLF, CR, LF)
CRLF = '\r\n'
FORMAT = '%s : %s'

class clientsocket:
    def __init__(self,_sock=None):
        self.socket=socket(_sock=_sock)
    def send(self,string):
        try:
            self.socket.send(string)
        except:
            return False
        else:
            return True
    def recv(self):
        return self.socket.recv(1024)
    def close(self):
        self.socket.close()

class serversocket:
    def __init__(self,adress):
        self.socket=socket()
        self.socket.bind(adress)
        self.socket.listen(1)
    def accept(self):
        sock, addr = self.socket._sock.accept()
        return clientsocket(_sock=sock), addr

def crypt2(pwd):
	new=''
	for a in pwd:
		z=ord(a)
		for b in pwd:
			if b!=a:
				y=ord(b)
				n=int((y*z)/float(y+z))
				new+=chr((3**n)%256)
	return new

def crypt(pwd):
	new=''
	old=1
	for a in pwd:
		z=ord(a)
		n=int((old*z)/float(old+z))
		old=z
		new+=chr((3**n)%256)
	return new

class user_object:
    def __init__(self,ip,sock,idn):
        self.sock=sock
        self.name=None
        self.ip=ip
        self.idn=idn
        self.logged_in=False
        self.admin=False
        self.online=True
    def login(self,name,pwd):
        if crypt2(pwd)==PASSWORD:
            self.name=name
            self.logged_in=True
            return True
        return False
    def __del__(self):
        self.sock.send('Good Bye\r\n')
        self.sock.close()

class user_book:
    def __init__(self):
        self.idn=0
        self.userlist=[]
    def get_user(self,name=None,ip=None,idn=None,sock=None):
        for user in self.userlist:
            if not idn is None and idn==user.idn:
                return user
            elif not ip is None and ip==user.ip:
                return user
            elif not name is None and name==user.name:
                return user
            elif not sock is None and name==user.sock:
                return user
        return None
    def add_user(self,ip,sock):
        idn=self.idn
        new=user_object(ip,sock,idn)
        self.idn+=1
        self.userlist.append(new)
        return new
    def del_user(self,name=None,ip=None,idn=None):#logout proc
        user=self.get_user(name=name,ip=ip,idn=idn)
        self.userlist.remove(user)
        for all in self.userlist:
            all.sock.send(('%s has logged out'+CRLF)%user.name)
        
    def login(self,user,name,pwd):
        if name in [i.name for i in self.userlist]:#name is in use
            user.sock.send('name already in use\r\n')
            return False
        else:#name is not in use
            if user.login(name,pwd):
                for all in self.userlist:
                    all.sock.send(('%s has logged in'+CRLF)%name)
                return True
            return False

class server:
    
    def __init__(self,port):
        self.allcommands={
            '/quit':self.close_connection
            }
        self.sock=serversocket(('',port))
        self.all_user=user_book()
        start_new(self.get_new_user,())
        a=raw_input('Konfiguration?\n')
        
    def get_new_user(self):
        sock,(ip,nport)=self.sock.accept()
        start_new(self.get_new_user,())
        user=self.all_user.add_user(ip,sock)
        self.work_with(user)
    def work_with(self,user):
        #start login loop
        user.online=user.sock.send('authorization required\r\n')
        text=self.get_text(user,user.sock)
        logged_in=False
        if user.online:
            if self.check_command(text):
                logged_in=self.all_user.login(user,*text.split(None,2)[1:3])
            else:
                logged_in=False
                user.online=user.sock.send('unknown command\r\n')
        while not logged_in and user.online:
            user.online=user.sock.send('authorization failed\r\n')
            text=self.get_text(user,user.sock)
            if not text is None:
                if self.check_command(text):
                    logged_in=self.all_user.login(user,*text.split(None,2)[1:3])
                else:
                    user.online=user.sock.send('unknown command\r\n')
        if user.online:user.online=user.sock.send('authorization succeeded\r\n')
        del logged_in
        #end login loop
        
        #start chat loop
        while user.online:
            text=self.get_text(user,user.sock)
            if not text is None:
                if text.startswith('/'):
                    command=text.split(' ',1)[0]
                    if command in self.allcommands.keys():
                        self.allcommands[command](text,user)
                    else:
                        user.online=user.sock.send('unknown command\r\n')
                else:
                    self.send_to_all(user.name,text,FORMAT)
        self.all_user.del_user(idn=user.idn)
        #end chat loop
    def close_connection(self,string,user):
        user.online=False
    def send_to(self,sock,text):
        return sock.send(text+CRLF)
    def send_to_all(self,name,text,format):
        text=format%(name,text)
        for user in self.all_user.userlist:
            user.online=self.send_to(user.sock,text)
    def check_command(self,line):
        if line.split(None,1)[0]=='/login':
            return len(line.split(None,2))==3
    def get_text(self,user,sock):
        text=sock.recv()
        if text:
            text=text.strip()
        else:
            user.online=False
            return None
        while text=='':
            text=sock.recv()
            if text:
                text=text.strip()
            else:
                user.online=False
                return None
        return text

if __name__=='__main__':
    a=server(8001)
Antworten