2014-01-13 5 views
14

У меня есть «серверный» сценарий python, работающий на одной из локальных сетевых машин, ожидающий подключения клиентов, и передает им некоторую работу. Код сервера и клиента оба были написаны и работают как ожидалось ...Обнаружение службы Python: реклама службы через локальную сеть

Проблема в том, что этот сервер может работать с любого компьютера в локальной сети, поэтому я не могу жестко закодировать адрес в скрипт ... Я сразу же подумал, могу ли я сделать рекламу машины о ее существовании, и клиенты могут ответить на это. Это можно сделать в Python со стандартной библиотекой? У меня действительно нет времени скачивать скрученные или торнадо и узнавать о них, к сожалению, поэтому мне нужно что-то простое.

Я попытался больше об этом подумать и понял, что у меня может быть одна статическая IP-машина, где серверы регистрируют/отменяют регистрацию, а клиенты могут искать серверы оттуда. Похоже, как торрент-трекер. Это нужно сделать, если я не могу легко использовать рекламный подход к сервису.

+1

Общим способом обнаружения локальных служб является использование [сетевой широковещательной передачи] (http://en.wikipedia.org/wiki/Broadcast_address#IP_networking). Вам не нужно жестко указывать конкретные IP-адреса, если вы используете его, и не имеете центральной службы. – goncalopp

+0

. Я не уверен, будет ли это легко или сложно сделать на питоне, но один из способов его обработки - через многоадресную 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) 

Discovery:

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

Есть ли способ сделать эту работу, когда сторона Discovery не знает, на каком порту находится диктор? –

+1

@SalimFadhley TCP/UDP-связь всегда происходит на пару хостов, портов, поэтому я предполагаю, что нет никакого способа сделать это (запрет на последовательное выполнение всех портов или захват всего трафика на интерфейсе). Есть ли причина, по которой вы не можете использовать фиксированный (высокий) порт? – goncalopp

+1

Путь лучше всех SSDP, UPnP, SLP и т. Д. спасибо – Epoc