# Parallel Python Software: http://www.parallelpython.com
# Copyright (c) 2005-2008, Vitalii Vanovschi
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the author nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.
"""Parallel Python Software, Auto-Discovery Service
http://www.parallelpython.com - updates, documentation, examples and support
forums
"""
import socket, sys, time, logging, thread
copyright = "Copyright (c) 2005-2008 Vitalii Vanovschi. All rights reserved"
version = "1.5"
# broadcast every 10 sec
BROADCAST_INTERVAL = 10
class Discover:
def __init__(self, base, isclient=False):
self.base = base
self.hosts = []
self.isclient = isclient
def run(self, address):
self.address = address
self.bsocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.bsocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.bsocket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
self.bsocket.connect(address)
try:
self.listen(address)
except:
sys.excepthook(*sys.exc_info())
def broadcast(self):
if self.isclient:
logging.debug("Client sends initial broadcast to (%s, %i)"
% self.address)
self.bsocket.sendall("C")
else:
while True:
logging.debug("Server sends broadcast to (%s, %i)"
% self.address)
self.bsocket.sendall("S")
time.sleep(BROADCAST_INTERVAL)
def listen(self, address):
logging.debug("Listening (%s, %i)" % address)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.bind(address)
thread.start_new_thread(self.broadcast, ())
while True:
try:
message, (host, port) = s.recvfrom(1024)
remote_address = (host, address[1])
id = host + ":" + str(address[1])
logging.debug("Discovered host (%s, %i) message=%c"
% (remote_address + (message[0],)))
if not self.base.autopp_list.get(id, 0) and self.isclient \
and message[0] == 'S':
logging.debug("Connecting to host %s" % (id,))
thread.start_new_thread(self.base.connect1,
remote_address+(False,))
if not self.isclient and message[0] == 'C':
logging.debug("Replying to host %s" % (id,))
self.bsocket.sendall("S")
except:
logging.error("An error has occured during execution of "
"Discover.listen")
sys.excepthook(*sys.exc_info())
syntax highlighted by Code2HTML, v. 0.9.1