2014-01-13 161 views
14

我有一臺運行在本地網絡機器上的「服務器」python腳本,它等待客戶端連接,並傳遞給他們一些工作。服務器和客戶端代碼已經寫入,並且正在按預期工作...Python服務發現:通過本地網絡發佈服務

問題是,此服務器可能從本地網絡中的任何計算機上運行,​​因此我無法硬編碼地址腳本......我立刻想知道我是否可以讓機器做廣告,客戶可以對此做出迴應。 Python在標準庫中可行嗎?不幸的是,我真的沒有時間下載扭曲或龍捲風並瞭解它們,所以我需要一些簡單的東西。

我試着更多地考慮它,並意識到我可以有一臺靜態IP機器,其中服務器註冊/取消註冊,客戶機可以從那裏尋找服務器。有點像洪流跟蹤器,我想。如果我無法輕鬆地完成服務廣告方法,那就必須這樣做。

+1

進行本地服務發現的常用方法是使用[網絡廣播](http://en.wikipedia.org/wiki/Broadcast_address#IP_networking)。你不需要硬編碼特定的IP地址,如果你使用它,也沒有一箇中央服務 – goncalopp

+0

我不確定這是否會很容易或很難做到在Python中,但一種方式來處理它是通過多播DNS。 – cnicutar

+0

@goncalopp謝謝,我研究了一下,它導致了非常「深刻」的教程,經常使用外部庫。我將嘗試研究組播DNS .. – Mazyod

回答

20

在本地網絡上執行服務通告/發現的簡單方法是通過廣播UDP數據包。

常量:

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

公告:

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) 

發現:

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):] 

此代碼被改編從demo on python.org

+0

發現方不知道播音員在哪個端口上,有沒有辦法使這項工作成爲可能? –

+1

@SalimFadhley TCP/UDP通信總是發生在主機端口對上,所以我的猜測是沒有辦法做到這一點(禁止連續嘗試所有端口或捕獲接口上的所有流量)。有沒有理由不能使用固定(高)端口? – goncalopp

+1

比所有SSDP,UPnP,SLP等都要好。謝謝 – Epoc