2014-01-13 9 views
14

ich einen „Server“ Python-Skript haben auf einem der lokalen Netzwerk-Rechner ausgeführt wird, die für die Kunden wartet zu verbinden, und übergibt sie einige Arbeit zu tun. Der Server- und der Client-Code wurden beide geschrieben und funktionieren wie erwartet ...Python Service Discovery: Werbung einen Dienst über ein lokales Netzwerk

Das Problem ist, dass dieser Server von einem beliebigen Computer im lokalen Netzwerk ausgeführt werden kann, daher kann ich die Adresse nicht in der Skript ... Ich habe mich sofort gefragt, ob ich eine Maschine für ihre Existenz werben kann, und Kunden können darauf reagieren. Ist das in Python mit der Standardbibliothek machbar? Ich habe wirklich keine Zeit, Twisted oder Tornado herunterzuladen und lerne darüber, leider, also brauche ich etwas Einfaches.

Ich habe versucht, mehr darüber nachzudenken, und erkennen ich eine einzige statische IP-Maschine haben kann, wo Server registrieren/unregister aus und Clients für Server von dort suchen. Ein bisschen wie ein Torrent-Tracker, denke ich. Das muss ich tun, wenn ich den Service-Werbemethode nicht leicht machen kann.

+1

einen [Netzwerk-Broadcast] verwendet (http://en.wikipedia.org/wiki/Broadcast_address#IP_networking) Ein üblicher Weg, lokalen Service-Entdeckung zu tun. Sie benötigen keine bestimmten IP-Adressen codieren, wenn Sie es verwenden, noch einen zentralen Service – goncalopp

+0

Ich bin nicht sicher, ob dies leicht oder schwer sein wird, in Python zu tun, sondern eine Möglichkeit, es zu handhaben über Multicast DNS ist. – cnicutar

+0

@goncalopp Danke, ich habe das ein wenig untersucht und es führt zu sehr "tiefen" Tutorials, die oft eine externe Bibliothek verwenden. Ich werde versuchen, den Multicast-DNS zu erforschen .. – Mazyod

Antwort

20

Eine einfache Möglichkeit, Service-Ankündigung/Entdeckung im lokalen Netzwerk zu tun, ist UDP-Pakete zu senden.

Konstanten:

PORT = 50000 
MAGIC = "fna349fn" #to make sure we don't confuse or get confused by other programs 

Ankündigung:

from time import sleep 
from socket import socket, AF_INET, SOCK_DGRAM, SOL_SOCKET, SO_BROADCAST, gethostbyname, gethostname 

s = socket(AF_INET, SOCK_DGRAM) #create UDP socket 
s.bind(('', 0)) 
s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1) #this is a broadcast socket 
my_ip= gethostbyname(gethostname()) #get our IP. Be careful if you have multiple network interfaces or IPs 

while 1: 
    data = MAGIC+my_ip 
    s.sendto(data, ('<broadcast>', PORT)) 
    print "sent service announcement" 
    sleep(5) 

Entdeckung:

from socket import socket, AF_INET, SOCK_DGRAM 

s = socket(AF_INET, SOCK_DGRAM) #create UDP socket 
s.bind(('', PORT)) 

while 1: 
    data, addr = s.recvfrom(1024) #wait for a packet 
    if data.startswith(MAGIC): 
     print "got service announcement from", data[len(MAGIC):] 

Dieser Code angepasst wurde vom demo on python.org

+0

Gibt es eine Möglichkeit, dies zu tun, wo die Discovery-Seite nicht weiß, auf welchem ​​Port der Ansager ist? –

+1

@SalimFadhley TCP/UDP-Kommunikation geschieht immer auf einem Host, Port-Paar, so meine Vermutung ist, dass es keine Möglichkeit gibt, das zu tun (abgesehen alle Häfen nacheinander versuchen oder den gesamten Verkehr auf der Schnittstelle Erfassung). Gibt es einen Grund, warum Sie keinen festen (hohen) Port verwenden können? – goncalopp

+1

Viel besser als alle diese SSDP, UPnP, SLP und was auch immer. Vielen Dank – Epoc

Verwandte Themen