2014-01-13 77 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