Seite 1 von 1

Informationen über IP -Adressen..

Verfasst: Freitag 12. Dezember 2008, 18:17
von pysq
Hallo,

ich programmiere ein Netzwerkspiel (Server, Client).
Gibt es eine Möglichkeit bei Python unter Windows via Broadcast o.ä. eine Liste mit verfügbaren Server in einem lokalen Netzwerk (z. B. 192.168.0.x) zu erstellen?

Ich glaube es ist dazu notwendig zunächst erst einmal notwendig, mit Python die eigene IP-Adresse herauszufinden.

mfg pysq

Verfasst: Samstag 13. Dezember 2008, 12:31
von limepix
Hi pysg!

vor einem ähnlichem problem bin ich selber auch gesessen...
ich wollte einfach ein paar nachrichten durch ein netzsegment schicken und jeder der einen "empfänger" offen hatte hat diese dann empfangen...

ich denke, was du dir mal anschauen solltest ist die seite

http://pyro.sourceforge.net/

nach ca ner halben std einlesen in die doku, hats dann auf anhieb geklappt...

ich hoffe ich konnte dir weiter helfen!


EDIT:Ach ja, was ich vergessen habe - mit pyro musst du dich nicht um IP Adressen kümmern... dieser "namensdienst" bedient sich eines bereits fertig eingebautem broadcast mechanismus.

Verfasst: Samstag 13. Dezember 2008, 16:30
von Y0Gi
Nach Q3A-Servern kann man so scannen: Arena Lurker. Je nach Spiel sehen die Ports, Anfragen und Antworten unterschiedlich aus.

Du kannst dich an bestehenden Protokollen orientieren und den Server deines Spiels einfach auf einem UDP-Port nach Broadcasts lauschen lassen.

PyRo ist meiner Ansicht nach nicht so geeignet.

Du kannst dir RakNet ansehen und schauen, ob du mit den Lizenzbedingungen und den Python-Bindings (IIRC "pyraknet") klar kommst.

Verfasst: Sonntag 14. Dezember 2008, 22:03
von pysq
@ limepix:
beim Ausführen der Setup (Pyro-3.8.1.win32.exe) kommt etwa folgender Fehler:
Anwendung konnte nicht gestartet werde [...] Side-by-Side Konfiguration ungültig.

@YOGi:
das Prinzip wie nach den Q3A Servern gesucht könnte zu meinem Code passen. Ich hab erstmal pygtk installiert.
Allerdings erhalte ich bei import gtk einen importerror von gobject??

mfg pysq

Verfasst: Sonntag 14. Dezember 2008, 22:23
von Leonidas
pysq hat geschrieben:Allerdings erhalte ich bei import gtk einen importerror von gobject??
Dann brauchst du PyGObject.

Verfasst: Montag 15. Dezember 2008, 03:50
von Y0Gi
Du kannst auch das GTK-Geraffel rauswerfen (das zeigt und aktualisiert und ein Dock-Icon) und stattdessen ein paar `print`-Statements einwerfen.

Das hier reicht:

Code: Alles auswählen

if __name__ == '__main__':
    with Scanner() as scanner:
        print list(scanner.scan())
Den GTK-Teil sowie `MainLoop` und die GTK-Imports können dann raus.

Verfasst: Mittwoch 17. Dezember 2008, 21:38
von pysq
alles klar : ) ich habe gtk einfach erst einmal rausgeschmissen.
ich hab das ganze jetzt erst einmal mit einem einfachen UDP Server ausprobiert, aber

Code: Alles auswählen

self.socket.sendto(request, ('<broadcast>', port))
stellt mit einem Server nur eine sehr kurze Verbindung her, die praktisch sofort wieder zurückgesetzt wird. Der Server hat keine Zeit, über denselben socket wieder zu antworten. Wie kann ich realisieren, dass der Server antwortet?
Gibt es auch eine Möglichkeit, das ganze mit TCP Servern zu gestalten?.. wenn ja, dann wahrscheinlich wohl nur umständlich..

Hier ist nochmal der Code für den Scanner

Code: Alles auswählen

import socket

class Scanner(object):

    def __init__(self, timeout=2):
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.socket.settimeout(timeout)
        self.socket.bind(('', 0))
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.socket.close()

    def scan(self, port=50000):
        request = 'Nachricht'
        self.socket.sendto(request, ('<broadcast>', port))
        while True:
            try:
                data, addr = self.socket.recvfrom(1024)
                print data, addr
                yield data
            except socket.timeout:
                break

if __name__ == '__main__':
    s=Scanner()
    
    while True:
        print '* Scanning ...', i
        try:
            a=list(s.scan())
            print a
        except KeyboardInterrupt:
            print 'Ctrl-C pressed, aborting.'
            break
udp server

Code: Alles auswählen

import socket, time
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

try: 
    s.bind(("", 50000)) 
    while True: 
        daten, addr = s.recvfrom(1024)
        print daten, addr
        s.sendto('test',(addr[0], 50001))
        time.sleep(0.01)
finally:
        s.close()
mfg pysq

Verfasst: Sonntag 21. Dezember 2008, 15:26
von roschi
hallo!

hier nur mal ein ausschnitt aus einem programm, das ich geschrieben habe. es duerfte dir weiterhelfen.

hier ist der client:

Code: Alles auswählen

import select, socket

def search_computers(waittime=3, port=55099):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    try:
        s.sendto("PING", ("<broadcast>", port))
    except socket.error:
        return []

    clients = []
    while True:
        if select.select([s], [], [], waittime)[0]:
            data, addr = s.recvfrom(13)
            if data == "PONG" and not addr[0] in clients:
                try:
                    name = socket.gethostbyaddr(addr[0])[0] + " (" + addr[0] + ")"
                except socket.error:
                    name = addr[0]
                clients.append(name)
        else:
            break
    return clients
und hier der responder:

Code: Alles auswählen

import select, socket, threading

def start_ping_responder(port=55099):
    thrd = ResponderThread(port)
    thrd.setDaemon(1)
    thrd.start()

class ResponderThread(threading.Thread):
    def __init__(self, port):
        threading.Thread.__init__(self)
        self.port = port

    def run(self):
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        try:
            s.bind(("", self.port))
        except socket.error, why:
            print "error: %s" % why
            return
        while True:
            if select.select([s], [], [])[0]:
                data, addr = s.recvfrom(11)
                if data == "PING":
                    s.sendto("PONG", addr)
wenn du das ein wenig an deine beduerfnisse anpasst, dann duerfte es kein problem mehr sein die rechner zu finden.

lg
roschi

Verfasst: Montag 22. Dezember 2008, 16:54
von pysq
danke, das tut es!

Verfasst: Donnerstag 25. Dezember 2008, 11:01
von pysq
und noch einmal einen Nachtrag, eigene IP herausfinden:

Code: Alles auswählen

name = socket.gethostname()
ip = socket.gethostbyname(name)