# 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())