def create_broadcast_sockets(): sender = Socket(AF_INET, SOCK_DGRAM) sender.setsockopt(SOL_SOCKET, SO_REUSEADDR, True) sender.setsockopt(SOL_SOCKET, SO_BROADCAST, True) sender.bind(("", 0)) receiver = Socket(AF_INET, SOCK_DGRAM) receiver.settimeout(constants.broadcast_receiver_timeout) receiver.setsockopt(SOL_SOCKET, SO_REUSEADDR, True) receiver.setsockopt(SOL_SOCKET, SO_BROADCAST, True) receiver.bind(("", constants.broadcast_port)) return sender, receiver
class Bus(common.AutoClose): """ An Autobus bus. Busses manage a set of published services, and allow connecting to other services. A single bus listens on a single TCP port and multiplexes all published services over it. Bus is a subclass of ServiceProvider; the service it provides is a service exposing information about what other services, events, functions, and objects are present. (This service is more commonly known as the introspection service.) You normally won't have to know this; instances of Bus register themselves as services with themselves, so you don't need to do anything to make the introspection service work. """ def __init__(self, default_discoverers=True, default_publishers=True, port=None): """ Creates a new bus. The bus will listen on the specified port; if none is specified (which is the usual case), a port will be chosen from the ports not currently in use on this computer. If default_discoverers is True (the default), a default set of discoverers will be installed, and likewise for default_publishers. Right now, this simply installs a autobus2.discovery.BroadcastPublisher and autobus2.discovery.BroadcastDiscoverer. Others might be added in the future. """ # Number of times this bus has been __enter__'d. Allows it to be used # as a re-entrant context manager. self.context_enters = 0 if port is None: port = 0 # True once close() has been called self.closed = False # The TCP server that will listen for connections self.server = Socket() self.server.bind(("", port)) # TODO: make the backlog configurable self.server.listen(100) self.port = self.server.getsockname()[1] # Lock that nearly everything bus-related locks on self.lock = RLock() # PropertyTable whose keys are service ids and whose values are # instances of autobus2.local.LocalService self.local_services = PropertyTable() self.local_services.global_watch(self.local_service_changed) # Map of ids of discovered services to DiscoveredService instances self.discovered_services = {} self.discovery_listeners = [] # List of (filter, function) tuples, where filter is an info object # filter and function is a function to be notified when a matching # service is created or deleted self.service_listeners = [] # Set of RemoteConnection instances that have been bound to a service self.bound_connections = set() # Set of discoverers registered on this bus self.discoverers = set() # Set of publishers registered on this bus self.publishers = set() if default_discoverers: self.install_discoverer(discovery.BroadcastDiscoverer()) if default_publishers: self.install_publisher(discovery.BroadcastPublisher()) Thread(name="autobus2.Bus.accept_loop", target=self.accept_loop).start() # Disable the introspection service for now. I'm seeing what would # happen if I have per-service introspection functions and objects, so # I'm disabling the bus-wide introspection service. # self._create_introspection_service() # # Register the bus as a service on itself. self.create_service({"type": "autobus.details", "pid": os.getpid()}, _IntrospectionService(self)) def accept_loop(self): """ Called on a new thread to accept socket connections to this bus. """ self.server.settimeout(1) while not self.closed: try: socket = None socket = self.server.accept()[0] self.setup_inbound_socket(socket) except SocketTimeout: # This happens when we time out, which is # normal. The 1-second timeout is to fix what appears to be a # bug with Windows not properly throwing an exception from # accept when another thread closes the socket. pass except: # This happens when the server socket is closed if socket: socket.close() # Make sure it's /really/ closed on the # off chance that something else caused the exception if not issubclass(sys.exc_type, SocketError): # Something else # happened print_exc() # print "Bus server died" return @synchronized_on("lock") def create_service(self, info, provider): """ Creates a new service on this bus. info is the info object to use for this service. provider is the instance of autobus2.service.ServiceProvider to publish; an instance of autobus2.providers.PyServiceProvider can be used to publish a simple Python object as a service. (This is how I expect most services to be published; writing a custom ServiceProvider subclass should rarely be needed.) The return value is an instance of local.LocalService. You can safely ignore it if you don't need it and don't plan on deleting the service before you close the bus itself. """ # Create a new id for the service service_id = messaging.create_service_id() self.set_remote_info_builtins(service_id, info) # Create the actual service object service = local.LocalService(self, service_id, info, provider) # Then store the service in our services map, which will cause the # service to be published through the introspection service and through # the bus's publishers (see self.local_service_changed). self.local_services[service_id] = service return service def _close_service(self, service): # This is called from LocalService.close, which will take care of # shutting down the service's connections and such. So the only thing # we really need to do here is delete the service from the local_service # map, which will cause self.local_service_changed to unpublish the # service and remove it from the introspection service. del self.local_services[service.id] @synchronized_on("lock") def setup_inbound_socket(self, socket): # Create a connection and then add it to our list of connections connection = local.RemoteConnection(self, socket) self.bound_connections.add(connection) def connect(self, host, port, service_id, timeout=10, open_listener=None, close_listener=None, fail_listener=None, lock=None): """ Opens a connection to the specified service on the specified host/port. The connection will be returned immediately. The actual connection to the server will be made as soon as possible in the future. If you need to block until the connection actually connects, call wait_for_connect on the returned Connection object. The connection will attempt to reconnect indefinitely whenever it is disconnected. If you don't want this behavior, specify a close_listener that calls the connection's close method. Timeout is the TCP timeout to use when connecting. The default is 10; this is usually a suitable default. You'll probably only want to increase this if you're working on a particularly latent network. open_listener and close_listener are functions accepting one argument. They will be called when the connection successfully connects and when the connection disconnects, respectively, and the connection itself will be passed in. They are both run synchronously on the connection's input thread, so it's guaranteed that, for example, the connection will not attempt to reconnect until close_listener has returned. Thus close_listener could be set to a function that just closes the specified connection in order to effectively disable the auto-reconnect feature of connections. """ return remote.Connection(self, host, port, service_id, timeout, open_listener, close_listener, fail_listener, lock) def connect_to(self, info_filter, timeout=10, open_listener=None, close_listener=None, fail_listener=None, lock=None): """ Locates the first service in the list of discovered services and uses self.connect to connect to it. The connection is then returned. This function will be going away soon. Service proxies (which can be obtained using self.get_service_proxy) are the replacement; a single service proxy is quite similar to this method, but it can follow the service across restarts of the underlying process publishing the service, which this method can't. """ with self.lock: for service_id, d in self.discovered_services.items(): if filter_matches(d.info, info_filter): host, port = d.locations.keys()[0] return self.connect(host, port, service_id, timeout, open_listener, close_listener, fail_listener, lock) raise exceptions.NoMatchingServiceException() def get_service_proxy(self, info_filter, bind_function=None, unbind_function=None, multiple=False): """ Returns a service proxy that will connect to services matching the specified info object filter. If multiple is False (the default), a single service proxy will be returned. If multiple is True, a multiple service proxy will be returned. See proxy.SingleServiceProxy and proxy.MultipleServiceProxy for the differences between the two. bind_function and unbind_function are optional functions that will be called when the proxy binds to and unbinds from a service, respectively. Binding is where a proxy discovers a new service matching its info filter and establishes a connection to it. Unbinding is where the proxy disconnects from said connection, usually because the service went away. """ with self.lock: if multiple: return proxy.MultipleServiceProxy(self, info_filter, bind_function, unbind_function) else: return proxy.SingleServiceProxy(self, info_filter) @synchronized_on("lock") def close(self): """ Closes this bus and all services registered on it. """ if self.closed: # Already closed return self.closed = True # First we shut down all of our discoverers for discoverer in self.discoverers: discoverer.shutdown() # Then we need to close all of our services. Closing a service causes # self._close_service to be called, which removes the service from the # list of services, which causes self.local_service_changed to be # called, which unpublishes the service. So we don't need to worry # about unpublishing services aside from this. for service_id in list(self.local_services): self.local_services[service_id].close() # Then we shut down all of the publishers for publisher in self.publishers: publisher.shutdown() # Then we shut down the server socket net.shutdown(self.server) # Then we close all of the connections currently connected to us for c in self.bound_connections: with no_exceptions: c.close() # And that's it! @synchronized_on("lock") def install_publisher(self, publisher): # Add the publisher to our list and start it up self.publishers.add(publisher) publisher.startup(self) # Then register all of our local services with the publisher for service in self.local_services.values(): publisher.add(service) @synchronized_on("lock") def remove_publisher(self, publisher): # Check to make sure that the publisher is already installed if publisher not in self.publishers: # TODO: Not sure why we're using __builtin__ here... raise __builtin__.ValueError("The specified publisher is not currently installed on this bus.") # Remove the publisher from our list of publishers self.publishers.remove(publisher) # Unpublish all of our services from the publisher for service in self.local_services.values(): if service.active: publisher.remove(service) # Then we shut down the publisher publisher.shutdown() @synchronized_on("lock") def install_discoverer(self, discoverer): # Add the discoverer to our list of discoverers, then start it up self.discoverers.add(discoverer) discoverer.startup(self) @synchronized_on("lock") def remove_discoverer(self, discoverer): # Check to make sure that the discoverer has already been installed if discoverer not in self.discoverers: # TODO: Ditto from remove_publisher raise __builtin__.ValueError("The specified discoverer is not currently installed on this bus.") # Remove the discoverer from our list of discoverers, then shut it # down self.discoverers.remove(discoverer) discoverer.shutdown() def set_local_info_builtins(self, host, port, service_id, info): new_info = info.copy() new_info["host"] = host new_info["port"] = port new_info["service"] = service_id return new_info def set_remote_info_builtins(self, service_id, info): """ Adds some values to the specified info object. The only one added right now is hostname, which is the value of socket.gethostname(). I haven't really standardized the list of values added here; I hope to at some point, though, and have all Autobus client libraries add the same ones. """ info["hostname"] = gethostname() @synchronized_on("lock") def discover(self, discoverer, host, port, service_id, info): # print "Discovered:", (host, port, service_id, info) # Add the relevant local builtins info = self.set_local_info_builtins(host, port, service_id, info) # Check to see if the specified service has been discovered yet, and if # it hasn't, create an entry for it is_new_service = False if service_id not in self.discovered_services: self.discovered_services[service_id] = DiscoveredService(info) is_new_service = True discovered_service = self.discovered_services[service_id] # Check to see if the specified host/port combination is already # present, and if it isn't, add it. if (host, port) not in discovered_service.locations: discovered_service.locations[(host, port)] = [] discoverer_list = discovered_service.locations[(host, port)] # Check to see if this discoverer has already discovered that host/port if discoverer in discoverer_list: print ("Warning: discoverer " + str(discoverer) + " tried to rediscover " + str((host, port, service_id)) + " with info " + str(info)) return # It hasn't, so add it. discoverer_list.append(discoverer) # The check to see if we need to notify listeners, and do so if we # need to if is_new_service: self.notify_service_listeners(service_id, host, port, info, DISCOVERED) @synchronized_on("lock") def undiscover(self, discoverer, host, port, service_id): # print "Undiscovered:", (host, port, service_id) # Check to see if the specified service has been discovered. if service_id not in self.discovered_services: print ("Warning: discoverer " + str(discoverer) + " tried to " "undiscover " + str((host, port, service_id)) + " when " "such a service does not exist.") return discovered_service = self.discovered_services[service_id] if (host, port) not in discovered_service.locations: print ("Warning: discoverer " + str(discoverer) + " tried to " "undiscover " + str((host, port, service_id)) + " when " "that host/port has not yet been discovered.") return discoverer_list = discovered_service.locations[(host, port)] if discoverer not in discoverer_list: print ("Warning: discoverer " + str(discoverer) + " tried to " "undiscover " + str((host, port, service_id)) + " when " "this discoverer hasn't discovered that host/port yet.") return discoverer_list.remove(discoverer) if not discoverer_list: if discovered_service.locations.keys()[0] == (host, port): # We're # removing the first (and therefore default) location, so if # there's another location, we need to let the service # listeners know that there's a new default location if len(discovered_service.locations) > 1: # There will be # another location even after we delete this one new_host, new_port = discovered_service.locations.keys()[1] if not self.closed: # Don't issue changes if we're shutting down self.notify_service_listeners(service_id, new_host, new_port, discovered_service.info, CHANGED) del discovered_service.locations[(host, port)] if not discovered_service.locations: # That was the last location # available for this service, so we delete the service itself, # and notify listeners that it was deleted del self.discovered_services[service_id] self.notify_service_listeners(service_id, host, port, discovered_service.info, UNDISCOVERED) @synchronized_on("lock") def add_service_listener(self, listener, info_filter=None, initial=False): """ Listens for changes in services that are available. listener is a function listener(service_id, host, port, info, event) which will be called whenever a service becomes available, a service disappears, or the host/port that should be used to access a particular service changes. service_id is the id of the service; host/port is the host/port at which the service can be found, info is the service's info object, and event is one of DISCOVERED, UNDISCOVERED, or CHANGED. If info_filter is a dictionary, only services with info objects matching that particular filter (as per the filter_matches function) will cause the listener to be called. If info_filter is None (the default), or the empty dictionary (since all info objects match the empty dictionary), the listener will be called for all services. If initial is True, the listener will be immediately (and synchronously) called once for each service that already exists, passing in DISCOVERED as the event. Otherwise, the listener will only be called once the next """ # Add the listener to our list of listeners self.service_listeners.append((info_filter, listener)) # Check to see if we're supposed to notify the listener about all # matching services that already exist if initial: # Scan all of the services for service_id, discovered_service in self.discovered_services.items(): if filter_matches(discovered_service.info, info_filter): # If this service matches, notify the listener about it host, port = discovered_service.locations.keys()[0] with print_exceptions: listener(service_id, host, port, discovered_service.info, DISCOVERED) @synchronized_on("lock") def remove_service_listener(self, listener, initial=False): # Scan the list of listeners and remove this one. Inefficient, it's # true, and I hope to make it more efficient later on. for index, (info_filter, l) in enumerate(self.service_listeners[:]): # See if we've hit the right listener if l == listener: # If we have, remove the listener del self.service_listeners[index] if initial: # Scan through the list of services for service_id, discovered_service in self.discovered_services.items(): if filter_matches(discovered_service.info, info_filter): # This service matched, so we notify this # listener that the service was removed with print_exceptions: listener(service_id, None, None, None, UNDISCOVERED) # We've found our listener and deleted it, so we return now return def notify_service_listeners(self, service_id, host, port, info, event): for filter, listener in self.service_listeners: if filter_matches(info, filter): with print_exceptions: listener(service_id, host, port, info, event) def local_service_changed(self, service_id, old, new): """ Called (by the local_services property table) when services come and go. All we really need to do is publish/unpublish the service. """ if old: for publisher in self.publishers: publisher.remove(old) if new: for publisher in self.publishers: publisher.add(new)
def run_server(server_port): """Run the UDP pinger server """ # Create the server socket (to handle UDP requests using ipv4), make sure # it is always closed by using with statement. server_socket = Socket(socket.AF_INET, socket.SOCK_DGRAM) # The socket stays connected even after this script ends. So in order # to allow the immediate reuse of the socket (so that we can kill and # re-run the server while debugging) we set the following option. This # is potentially dangerous in real code: in rare cases you may get junk # data arriving at the socket. server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # Set the server port server_socket.bind(("", server_port)) # Start accepting ping requests print ("Ping server ready on port", server_port) while True: # Receive message and send one back _, client_address = server_socket.recvfrom(1024) server_socket.sendto("Pong".encode(), client_address) return 0
def main(): register_builtin_interface() server = Socket() if len(sys.argv) > 1: server_port = int(sys.argv[1]) else: server_port = DEFAULT_PORT print "Listening on port " + str(server_port) server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) server.bind(("", server_port)) server.listen(50) Thread(target=process_event_queue).start() print "\nAutobus has successfully started up." try: while True: socket, address = server.accept() connection = Connection(socket, address) event_queue.put((connection.id, discard_args(connection.register)), block=True) connection.start() except KeyboardInterrupt: print "KeyboardInterrupt received, shutting down" event_queue.put((None, None), block=True) print "Event queue has been notified to shut down" except: print "Unexpected exception occurred in the main loop, shutting down. Stack trace:" print_exc() event_queue.put((None, None), block=True) print "Event queue has been notified to shut down" server.close()
def redirector(): """ Redirects all incoming traffic through the proxy. """ PROXY_HOST = environ.get("PROXY_HOST") PROXY_PORT = environ.get("PROXY_PORT", 1080) setdefaultproxy(PROXY_TYPE_SOCKS5, PROXY_HOST, PROXY_PORT) server = Socket(AF_INET, SOCK_STREAM) server.bind(("127.0.0.1", 42000)) server.listen(5) while True: client_socket, (src_host, src_port) = server.accept() (dst_host, dst_port) = get_original_destination(client_socket) logger.info( f"Intercepted connection from {src_host}:{src_port} to {dst_host}:{dst_port}" ) proxy_socket = SocksSocket() proxy_socket.connect((dst_host, dst_port)) bidirectional_copy(client_socket, proxy_socket)
def main(): parser = argparse.ArgumentParser() parser.add_argument('--port', '-p', default=2000, type=int, help='port to use') args = parser.parse_args() server_socket = Socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server_socket.bind(('', args.port)) server_socket.listen(1) print "server running" while True: connection_socket = server_socket.accept()[0] request = connection_socket.recv(1024) reply = http_handler(request) connection_socket.send("HTTP/1.1 200 OK\n") connection_socket.send("\n") connection_socket.send(reply) connection_socket.close() print "received request" print "reply sent" return 0
class Server: def __init__(self, address, port, max_connections): self.socket = Socket() self.address = address self.port = port self.connections = max_connections def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): self.socket.__exit__(exc_type, exc_val, exc_tb) logging.info('Server closed') def start(self): logging.info('Starting server') try: self.socket.bind((self.address, self.port)) except OSError: logging.debug("Address already taken - {address}:{port}".format( address=self.address, port=self.port)) exit(1) self.socket.listen(self.connections) logging.info('Server has been started. Waiting for connections.') def close(self): self.socket.close() def accept(self): client_sock, client_addr = self.socket.accept() return client_sock, client_addr
class PyCashServer: HOST = '' # Symbolic name meaning all available interfaces PORT = 50007 def __init__(self): self.s = Socket(socket.AF_INET, socket.SOCK_STREAM) self.s.bind((self.HOST, self.PORT)) self.s.listen(3) def receveObject(self): conn, addr = self.s.accept() conn.settimeout(5.0) data = conn.recv(16) objString = '' while(data != None): objString += (data) conn.send(data) try: data = conn.recv(16) except: data = None x = json.loads(objString) return obj(x)
def main(): parser = argparse.ArgumentParser() parser.add_argument('--port', '-p', default=8080, type=int, help='Port to use') args = parser.parse_args() try: server_socket = Socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, BUFFER_SIZE) server_socket.bind(('', args.port)) server_socket.listen(1) cache_dict = {} print "Proxy server ready..." while True: try: connection_socket = server_socket.accept()[0] t = Thread(target=handle_http, args=[cache_dict, connection_socket]) t.setDaemon(1) t.start() t.join() except socket.error, e: print e finally: connection_socket.close()
def test_bind_in_range(sock: socket, port: int, tries: int = 0): """Wrapper around socket binding that will try to bind to the given port, catching any errors and trying again at one plus that port, up to the number of times defined in the variable LISTENER_PORT_RANGE. Helps to eliminate the need for setting listener port for multiple agents, or in situations where one of the ports in the default range is used. Args: sock (socket): socket to be bound port (int): start of range of ports to trying binding socket to tries (int, optional): position in the range of ports - ie number of tries Returns: None: Always returns None """ if tries > LISTENER_PORT_RANGE: orig_port = port - (LISTENER_PORT_RANGE + 1) assert test_sock_name(sock), \ 'Failed to bind to a port from %s to %s' % (orig_port, port - 1) return try: sock.bind(('', port)) except OSError as error_msg: LOGGER.debug('Failed to bind to port %s, error: %s, trying again...', port, error_msg) test_bind_in_range(sock, port + 1, tries + 1)
def anetListen(s: socket.socket, host: str, port: Opt[int], backlog: int) -> None: try: s.bind((host, port)) s.listen(backlog) except OSError: s.close() raise
def remote(cls, port, environment, max_episode_timesteps=None, **kwargs): socket = Socket() socket.bind(('', port)) socket.listen(1) connection, address = socket.accept() socket.close() super().remote(connection=connection, environment=environment, max_episode_timesteps=max_episode_timesteps, **kwargs)
def start(_socket: socket): _socket.bind(('', port)) _socket.listen(15) print('Server on! Waiting for connections.') while 1: connection, remote_address = _socket.accept() thread = Thread(target=handle_new_connections, args=(connection, remote_address)) thread.start()
def _listen(self, sock: socket.socket): """Open up a listener for a client to connect to. Args: sock (socket.socket): connection to client """ sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind((self.host, self.port)) sock.listen(1) self._sock, _ = sock.accept()
def server_init(sock: socket.socket, address: tuple, timeout): sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.settimeout(timeout) try: sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) except AttributeError: pass except socket.error as e: if e.errno != errno.ENOPROTOOPT: raise sock.bind(address)
def start_server(): # import needed libraries from random import randint from socket import socket as Socket from socket import AF_INET, SOCK_STREAM # Server Setup HOSTNAME = '' # blank so any address can be used PORTNUMBER = 12345 # number for the port BUFFER = 1024 # size of the buffer SERVER_ADDRESS = (HOSTNAME, PORTNUMBER) # make the server address a tuple SERVER = Socket(AF_INET, SOCK_STREAM) # create the server socket print("SERVER >> Socket successfully created") # print out socket successfully created SERVER.bind(SERVER_ADDRESS) # bind the socket to the address print("SERVER >> Socket binded to 12345") # print out socket successfully binded SERVER.listen(2) # start listening on the socket for connections print("SERVER >> Socket is listening") # print out verification that socket is listening # receive client connections CLIENT1, CLIENT1_ADDRESS = SERVER.accept() # receive the connection from client1 and save the socket and client address CLIENT2, CLIENT2_ADDRESS = SERVER.accept() # receive the connection from client2 and save the socket and client address print('SERVER >> Got connection from ', CLIENT1_ADDRESS) # print connection1 verification string print('SERVER >> Got connection from ', CLIENT2_ADDRESS) # print connection2 verification string # loop until message received is "QUIT" while True: MESSAGE1 = CLIENT1.recv(BUFFER).decode() # receive message1 from client1 and decode it REPLY1 = "" # instantiate reply1 as an empty string MESSAGE2 = CLIENT2.recv(BUFFER).decode() # receive message2 from client2 and decode it REPLY2 = "" # instantiate reply2 as an empty string # if receive "QUIT" from client1, send "QUIT back to both clients and break out of loop to close the socket" if MESSAGE1 == "QUIT": REPLY1 = "QUIT" CLIENT1.send(REPLY1.encode()) CLIENT2.send(REPLY1.encode()) break # if receive "QUIT" from client2, send "QUIT back to both clients and break out of loop to close the socket" elif MESSAGE2 == "QUIT": REPLY2 = "QUIT" CLIENT2.send(REPLY2.encode()) CLIENT1.send(REPLY2.encode()) break # otherwise, reverse the messages received and send them back to clients else: length1 = len(MESSAGE1) # get MESSAGE1 length length2 = len(MESSAGE2) # get MESSAGE2 length REPLY1 = MESSAGE1[length1::-1] # make REPLY1 the MESSAGE1 reversed REPLY2 = MESSAGE2[length2::-1] # make REPLY2 the MESSAGE2 reversed CLIENT1.send(REPLY1.encode()) # send encoded REPLY1 to CLIENT1 CLIENT2.send(REPLY2.encode()) # send encoded REPLY2 to CLIENT2 print('SERVER >> Closing Socket, GOODBYE.') # print out break out of loop verification string SERVER.close() # close out the socket
def bind_socket(sock: socket.socket, channel: str = "can0") -> None: """ Binds the given socket to the given interface. :param sock: The socket to be bound :raises OSError: If the specified interface isn't found. """ log.debug("Binding socket to channel=%s", channel) sock.bind((channel, )) log.debug("Bound socket.")
def main(): # Command line arguments. Use a port > 1024 by default so that we can run # without sudo, for use as a real server you need to use port 80. parser = argparse.ArgumentParser() parser.add_argument('--port', '-p', default=2080, type=int, help='Port to use') args = parser.parse_args() # Create the server socket (to handle tcp requests using ipv4), make sure # it is always closed by using with statement. #with Socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket: ss = Socket(socket.AF_INET, socket.SOCK_STREAM) # COMPLETE (1) # The socket stays connected even after this script ends. So in order # to allow the immediate reuse of the socket (so that we can kill and # re-run the server while debugging) we set the following option. This # is potentially dangerous in real code: in rare cases you may get junk # data arriving at the socket. ss.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # COMPLETE (2) endpoint = ('', args.port) # COMPLETE (3) ss.bind(endpoint) ss.listen(1) print("server ready") while True: cs = ss.accept()[0] request = cs.recv(1024).decode('ascii') print(request) reply = http_handle(request) cs.send(reply.encode('ascii')) print("\n\nReceived request") print("======================") print(request.rstrip()) print("======================") print("\n\nReplied with") print("======================") print(reply.rstrip()) print("======================") return 0
def startServer(): socket = Socket() socket.bind((ADDRESS, PORT)) socket.listen() print(f"Listening on '{ADDRESS}:{PORT}'") while 1: connection, clientInfo = socket.accept() print(f"Client {clientInfo} connected") if listenClient(connection, clientInfo): return
class Server: def __init__(self): self.console = console.Console() threading.Thread(target=self.console.thread_start).start() logging.basicConfig( stream=self.console, level=logging.INFO, format='[%(levelname)s][%(asctime)s][%(name)s] %(message)s') self.logger = logging.getLogger("Server Main") self.addr = server_config["ipv4_addr"] self.port = server_config["port"] self.loggedin_users = {} self.command_queue = queue.Queue() self.user_db = sql.UserDB() threading.Thread(target=self.user_db.thread_start).start() self.chat_db = sql.ChatDB() threading.Thread(target=self.chat_db.thread_start).start() def stop(self): for i in self.client_list: if i != 0: self.logger.info("Stopping %d" % i) self.client_list[i].parser_queue.put( {flags.FLAG_INTERRUPT, None}) time.sleep(1) os._exit(0) def run(self): root = connection.RootConnection(self) self.client_list = {0: root} threading.Thread(target=root.thread_start).start() threading.Thread(target=self.thread_start).start() def thread_start(self): self.main_socket = Socket(AF_INET, SOCK_STREAM) self.main_socket.bind((self.addr, self.port)) self.main_socket.listen() self.logger.info("Server successfuly started on %s:%d (PID:%d)" % (self.addr, self.port, os.getpid())) while 1: client = connection.ClientConnection(self, *self.main_socket.accept()) self.client_list[client.client_id] = client threading.Thread(target=client.thread_start).start()
def listen(self): """ Bind and listen. :return: The open socket. :rtype: socket.socket """ address = (self.host, self.port) socket = Socket(AF_INET, SOCK_STREAM) socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) socket.bind(address) socket.listen(5) log.info('listening on: %d', self.port) return socket
def __init__(self): # Set up the interrupt socket interrupt_server = Socket() interrupt_server.bind(("localhost", 0)) interrupt_server.listen(1) self.interrupt_writer = Socket() self.interrupt_writer.setblocking(False) self.interrupt_writer.connect("localhost", interrupt_server.getsockname()[1]) self.interrupt_reader = interrupt_server.accept() interrupt_server.shutdown(SHUT_RDWR) interrupt_server.close() self.interrupt_reader.setblocking(False) self.interrupt_writer.setblocking(False)
def main(): dnsSocket = Socket(socket.AF_INET, socket.SOCK_STREAM) dnsSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # Comunicacao com o server ############################ dnsSocket.bind(('', 2010)) dnsSocket.listen(1) print('------------Conectou com o SERVER') connection_socket = dnsSocket.accept()[0] print('Aceitou conexão com o SERVER') msg = connection_socket.recv(1024).decode('ascii') domainName, ipAddress = msg.split("#") #domainName = connection_socket.recv(1024).decode('ascii') #print(domainName) #ipAddress = connection_socket.recv(1024).decode('ascii') print('Recebi do SERVER o dominio: ' + domainName) print('Recebi do SERVER o IP: ' + ipAddress) map[domainName] = ipAddress connection_socket.send('Mensagem do DNS para o SERVER'.encode('ascii')) ############################ # Comunicacao com o Client ############################ UDPServerSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) UDPServerSocket.bind(('localhost', 2001)) while (True): bytesAddressPair = UDPServerSocket.recvfrom(1024) domainName = bytesAddressPair[0].decode('ascii') address = bytesAddressPair[1] print('Recebi do Client: ' + domainName + ' ' + str(address)) if not domainName: break if (domainName in map): msg = map.get(domainName) #connection_socket.send(ipAddress.encode('ascii')) else: msg = 'Nao existe esse dominio' #connection_socket.send(msg.encode('ascii')) UDPServerSocket.sendto(msg.encode('ascii'), address) """
def bind_unused_port(sock: socket.socket, host: str = 'localhost') -> int: """Bind the socket to a free port and return the port number. This code is based on the code in the stdlib's test.test_support module.""" if sock.family in (socket.AF_INET, socket.AF_INET6) and sock.type == socket.SOCK_STREAM: if hasattr(socket, "SO_EXCLUSIVEADDRUSE"): try: sock.setsockopt(socket.SOL_SOCKET, socket.SO_EXCLUSIVEADDRUSE, 1) except socket.error: pass if sock.family == socket.AF_INET: if host == 'localhost': sock.bind(('127.0.0.1', 0)) else: sock.bind((host, 0)) elif sock.family == socket.AF_INET6: if host == 'localhost': sock.bind(('::1', 0, 0, 0)) else: sock.bind((host, 0, 0, 0)) else: raise CommunicationError("unsupported socket family: " + str(sock.family)) return sock.getsockname()[1]
def bind_unused_port( sock: socket.socket, host: Union[str, ipaddress.IPv4Address, ipaddress.IPv6Address] = 'localhost' ) -> int: """Bind the socket to a free port and return the port number. This code is based on the code in the stdlib's test.test_support module.""" if sock.family in (socket.AF_INET, socket.AF_INET6) and sock.type == socket.SOCK_STREAM: if hasattr(socket, "SO_EXCLUSIVEADDRUSE"): with contextlib.suppress(socket.error): sock.setsockopt(socket.SOL_SOCKET, socket.SO_EXCLUSIVEADDRUSE, 1) if not isinstance(host, str): host = str(host) if sock.family == socket.AF_INET: if host == 'localhost': sock.bind(('127.0.0.1', 0)) else: sock.bind((host, 0)) elif sock.family == socket.AF_INET6: if host == 'localhost': sock.bind(('::1', 0, 0, 0)) else: sock.bind((host, 0, 0, 0)) else: raise CommunicationError("unsupported socket family: " + str(sock.family)) return sock.getsockname()[1]
def listen_for_data(sock: socket.socket) -> None: """Make the socket listen for data forever.""" host = 'localhost' port = 41401 sock.bind((host, port)) sock.listen(1) while True: print('Waiting...') conn, addr = sock.accept() print(f'Connection from {addr}') if addr[0] != '127.0.0.1': continue with conn: data = receive_all(conn) parse_data(data)
def run_server(server_port): # Run UDP pinger server try: server_socket = Socket(socket.AF_INET, socket.SOCK_DGRAM) server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server_socket.bind(('', server_port)) print("Ping server ready on port", server_port) while True: _, client_address = server_socket.recvfrom(1024) server_socket.sendto("".encode(), client_address) finally: server_socket.close() return 0
def main(): HOSTNAME = '' # blank so any address can be used PORTNUMBER = 11267 # number for the port BUFFER = 80 # size of the buffer DEALER_ADDRESS = (HOSTNAME, PORTNUMBER) DEALER = Socket(AF_INET, SOCK_STREAM) DEALER.bind(DEALER_ADDRESS) DEALER.listen(1) print('dealer waits for player to connect') PLAYER, PLAYER_ADDRESS = DEALER.accept() print('dealer accepted connection request from ',\ PLAYER_ADDRESS) playGame(PLAYER, BUFFER) DEALER.close()
class SocketStream(Stream): def __init__(self, port): self.listener = Socket(AF_INET, SOCK_STREAM) self.listener.bind(('', port)) def open(self): self.listener.listen(1) self.socket, address = self.listener.accept() def read(self, size=1024): return self.socket.recv(size) def write(self, data): self.socket.sendall(data) def close(self): self.socket.close() self.listener.close()
def serverP(self): server = Socket(socket.AF_INET,socket.SOCK_DGRAM) server.settimeout(setup.DELAY_TIMEOUT) server.bind((self.IPAddress,self.Port)) while True: try: recv = server.recvfrom(setup.SIZE_BUFFER_RETURN) sock_Response = Response(recv) reply = (sock_Response.IPAddress,sock_Response.Port) if sock_Response.received == True: self.packet_response(sock_Response.Data) if sock_Response.Data.startswith(setup.PREFIX_CHECK): packet = self.generate_packet(setup.PREFIX_CHECK) if sock_Response.Data.startswith(setup.PREFIX_UPDATE): packet = self.generate_packet(setup.PREFIX_UPDATE) byte = str.encode(packet) server.sendto(byte,reply) self.log_server(reply,sock_Response) except Exception: pass
def discover(interface: str, timeout: float) -> Iterable[Host]: sock = Socket(AF_INET, SOCK_DGRAM) sock.settimeout(timeout) sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) sock.setsockopt(SOL_SOCKET, SO_BROADCAST, 1) sock.bind((interface, 34569)) request = Packet(0, 0, 1530, b'', fragments=0, fragment=0) sock.sendto(request.encode(), ('255.255.255.255', 34569)) while True: try: data, (host, _) = sock.recvfrom(Packet.MAXLEN) except Timeout: break packet = Packet.decode(data) if not packet.payload: continue reply = DiscoverReply.frompackets([packet]).host if reply.host != host: raise DVRIPDecodeError('wrong IP address ' 'reported') yield reply
def udp_listener(shutdown_event, session_start_event, session_stop_event): #chk server address path and remove it if there try: unlink(SERVER_ADDR) except OSError: if (path.exists(SERVER_ADDR)): raise sock = SOCKET(AF_UNIX, SOCK_DGRAM) sock.bind(SERVER_ADDR) while (not (shutdown_event.isSet())): try: while (not (shutdown_event.isSet())): data, address = sock.recvfrom(2048) if data: data = data.decode().split() if (data[0] == "start"): ret = start_session(data[1], shutdown_event, session_start_event, session_stop_event) sock.sendto(bytes(ret, "utf-8"), address) elif (data[0] == "note"): sock.sendto(bytes('go', "utf-8"), address) data, address = sock.recvfrom(2048) write_journal((("____________________ Note _________________________\n"), \ (str(data)), \ (datetime.now().strftime("%m/%d/%Y %H:%M:%S") + '\n\n'))) sock.sendto(bytes('ok', "utf-8"), address) elif (data[0] == "stop"): session_stop_event.set() sleep(0.2) shutdown_event.set() sleep(0.2) sock.sendto(bytes('bye', "utf-8"), address) else: break finally: sock.close() pass
def start_server(): # import needed libraries from random import randint from socket import socket as Socket from socket import AF_INET, SOCK_STREAM # Server Setup HOSTNAME = '' # blank so any address can be used PORTNUMBER = 11267 # number for the port BUFFER = 80 # size of the buffer SERVER_ADDRESS = (HOSTNAME, PORTNUMBER) SERVER = Socket(AF_INET, SOCK_STREAM) SERVER.bind(SERVER_ADDRESS) SERVER.listen(1) print('SERVER >> Waiting for player to connect.') PLAYER, PLAYER_ADDRESS = SERVER.accept() print('SERVER >> Accepted player connection request from ',\ PLAYER_ADDRESS) PASSWORD = "******" print(f'SERVER >> Password is {PASSWORD}') while True: print('SERVER >> Waiting for a guess from player.') GUESS = PLAYER.recv(BUFFER).decode() print('SERVER >> Received the following guess: ' + GUESS) if GUESS == PASSWORD: REPLY = 'You chose wisely.' else: REPLY = 'You chose poorly.' PLAYER.send(REPLY.encode()) if REPLY == 'You chose wisely.': break SERVER.close()
def listen(self): global listening, listenSocket listenSocket = Socket(AF_INET, SOCK_STREAM) listenSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) listenSocket.bind(('0.0.0.0', self.localPeer.addr[1])) listening = True listenSocket.listen(len(self.remotePeerDict)) try: while True: socket, addr = listenSocket.accept() msg = socket.recv(6) if msg[:4] == 'PEER': idx = int(msg[4:]) self.remotePeerDict[idx].onConnect(socket) elif msg == 'CLIENT': client = Peer('client', None) client.network = self client.onConnect(socket) except SocketError: pass
def bind_port(sock: socket.socket, host: str = HOST) -> int: """Bind the socket to a free port and return the port number. Relies on ephemeral ports in order to ensure we are using an unbound port. This is important as many tests may be running simultaneously, especially in a buildbot environment. This method raises an exception if the sock.family is AF_INET and sock.type is SOCK_STREAM, *and* the socket has SO_REUSEADDR or SO_REUSEPORT set on it. Tests should *never* set these socket options for TCP/IP sockets. The only case for setting these options is testing multicasting via multiple UDP sockets. Additionally, if the SO_EXCLUSIVEADDRUSE socket option is available (i.e. on Windows), it will be set on the socket. This will prevent anyone else from bind()'ing to our host/port for the duration of the test. """ if sock.family == socket.AF_INET and sock.type == socket.SOCK_STREAM: if hasattr(socket, "SO_REUSEADDR"): if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR) == 1: raise ValueError("tests should never set the SO_REUSEADDR " "socket option on TCP/IP sockets!") if hasattr(socket, "SO_REUSEPORT"): try: if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) == 1: raise ValueError("tests should never set the SO_REUSEPORT " "socket option on TCP/IP sockets!") except OSError: # Python's socket module was compiled using modern headers # thus defining SO_REUSEPORT but this process is running # under an older kernel that does not support SO_REUSEPORT. pass if hasattr(socket, "SO_EXCLUSIVEADDRUSE"): sock.setsockopt(socket.SOL_SOCKET, socket.SO_EXCLUSIVEADDRUSE, 1) sock.bind((host, 0)) port = sock.getsockname()[1] assert isinstance(port, int) return port
def main(): parser=argparse.ArgumentParser() parser.add_argument('--port','-p',default=2000,type=int,help='port to use') args=parser.parse_args() server_socket=Socket(socket.AF_INET,socket.SOCK_STREAM) server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) server_socket.bind(('',args.port)) server_socket.listen(1) print "server running" while True: connection_socket=server_socket.accept()[0] request=connection_socket.recv(1024) reply=http_handler(request) connection_socket.send("HTTP/1.1 200 OK\n") connection_socket.send("\n") connection_socket.send(reply) connection_socket.close() print "received request" print "reply sent" return 0
def bind_reuse(ip, port): sock = Socket() sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) sock.bind((ip, port)) return sock
def bind_naive(ip, port): sock = Socket() try: sock.bind((ip, port)) except socket.error as error: return error
def wait_connect(self): if self.needQuit: return self.init_graphic() self.informBoard = dashboard.InformBoard((10, 25), 15) test = 0 server = Socket(socket.AF_INET, socket.SOCK_STREAM) if not test: while 1: try: server.bind(("", config.Port)) break except socket.error as e: self.inform(str(e)) for event in pygame.event.get(): if event.type == QUIT: self.quit() break self.render_connection() sleep(1) server.listen(2) server.settimeout(0.0) player1 = Player(1, server) else: player1 = HumanPlayer(1) if self.add_human: player2 = HumanPlayer(2) # add handler for human player self.pyeventHandlers.append(player2) else: player2 = Player(2, server) players = [player1, player2, None] timer = pygame.time.Clock() # wait until connected 2 players finished = 0 player = players[finished] try: self.inform("waiting for AI to connect...") while finished < 2: for event in pygame.event.get(): if event.type == QUIT: self.quit() break if self.needQuit: break if player.connect(): self.add_player(player) self.inform("AI %s connected" % (player.name)) finished += 1 player = players[finished] self.render_connection() timer.tick(10) except KeyboardInterrupt: server.close() return False server.close() return True
import socket as Net from socket import socket as Socket import os,re,sys print Net.AF_INET,Net.SOCK_STREAM s = Socket(Net.AF_INET,Net.SOCK_STREAM) #get localhost name and ip address localhostName = Net.gethostname() localhostAddress = Net.gethostbyname(localhostName) print localhostName , localhostAddress try: s.bind((localhostAddress,10010)) print 'bind succeed!' s.listen(10) print 'start to listen!' except Exception as ex: print 'Error' , ex finally: s.close() print 'socket closed!'
class Server(Thread): ''' Subclass this class and override: handleQueue() interval() `close()` ''' def __init__(self, my_OneServer=OneServer, port=80, listen=1, accept_timeout=.5): # Pass in your subclassed OneServer Thread.__init__(self) self.queue = Queue() self.OneServer = my_OneServer self.listen = listen self.socket = Socket() self.socket.bind(('', port)) self.socket.settimeout(accept_timeout) self._go_on = Safe(True) self.oneServers = [] self.max_connection = Safe(4 * 32) self.showing_max_waring = False def setMaxConnection(self, number): self.max_connection.set(number) def getMaxConnection(self): return self.max_connection.get() def interval(self): ''' Override this. ''' pass def handleQueue(self, intent): ''' Override this. ''' pass def __handleQueue(self, intent): if type(intent) is DeregisterOneServer: self.oneServers.remove(intent.oneServer) else: self.handleQueue(intent) def close(self): if self.isAlive(): with self._go_on: self._go_on.value = False #self.join() public method def onConnect(self, addr): pass # to override. def run(self): self.socket.listen(self.listen) log('listening at', gethostbyname(gethostname()), '...') while self._go_on.get(): if len(self.oneServers) >= self.getMaxConnection(): if not self.showing_max_waring: log('Max connection reached. ') self.showing_max_waring = True else: if self.showing_max_waring: log("Max connection isn't reached anymore. ") self.showing_max_waring = False try: socket, addr = self.socket.accept() log(addr, 'Accepted. ') self.onConnect(addr) oneServer = self.OneServer(addr, socket, self.queue) self.oneServers.append(oneServer) oneServer.start() except timeout: pass try: while self._go_on.get(): self.__handleQueue(self.queue.get_nowait()) except Empty: pass self.interval() self.socket.close() log('Closing', len(self.oneServers), 'oneServers.') for oneServer in self.oneServers: oneServer.close() log('Server thread has stopped. ')
# L-40 MCS 260 Wed 20 Apr 2016 : mc4pi2.py """ Implements server for Monte Carlo method for pi, with two clients. Server dispatches the seeds and collects results. """ from socket import socket as Socket from socket import AF_INET, SOCK_STREAM HOSTNAME = '' # blank so any address can be used NUMBER = 11267 # number for the port BUFFER = 80 # size of the buffer SERVER_ADDRESS = (HOSTNAME, NUMBER) SERVER = Socket(AF_INET, SOCK_STREAM) SERVER.bind(SERVER_ADDRESS) SERVER.listen(2) print('server waits for connections...') FIRST, FIRST_ADDRESS = SERVER.accept() SECOND, SECOND_ADDRESS = SERVER.accept() FIRST.send('1'.encode()) SECOND.send('2'.encode()) print('server waits for results...') PART1 = FIRST.recv(BUFFER).decode() PART2 = SECOND.recv(BUFFER).decode()
#!usr/bin/python import random from socket import socket as Socket from socket import AF_INET, SOCK_STREAM HOSTNAME = 'localhost' PORTNAME = 11271 BUFFER = 80 DEALER_ADDRESS = (HOSTNAME, PORTNAME) DEALER = Socket(AF_INET, SOCK_STREAM) DEALER.bind(DEALER_ADDRESS) DEALER.listen(1) print('dealer waits for player to connect') PLAYER, PLAYER_ADDRESS = DEALER.accept() print('dealer accepted connection request from ',\ PLAYER_ADDRESS) WORDS = ['GoNavy'] word = WORDS secret_word = [] count = 1 while True: for letter in word: secret_word.append('_') secret_word[0] = word[0]
def main(): s = Socket(AF_INET, SOCK_DGRAM) s.bind(("", 53)) while True: message = s.recv(1500) print repr(from_wire(message))
class SixjetServer(Thread): """ A sixjet server. Server instances listen on both a specified port for native sixjet commands and on an Autobus 2 service. They are created with a function that will be used to write bytes to the parallel port; you'll typically pass an instance of parallel.Parallel's setData method, but any function accepting an integer will do. """ def __init__(self, write_function, port, bus, service_extra={}): """ Creates a new sixjet server. write_function is the function to use to write data to the parallel port. port is the port on which the native protocol listener should listen. service_extra is an optionally-empty set of values that will be added to the Autobus 2's service info dictionary. (Keys such as type will be added automatically, but such keys present in service_extra will override the ones added automatically.) bus is the Autobus bus to use. You can usually just use: from autobus2 import Bus with Bus() as bus: server = SixjetServer(..., bus, ...) ... and things will work. If write_function is None, a new parallel.Parallel instance will be created, and its setData method used. """ Thread.__init__(self) if write_function is None: import parallel self._parallel = parallel.Parallel() write_function = self._parallel.setData else: self._parallel = None # The event queue. Events can be pushed from any thread, but can only # be read and processed from the SixjetServer's run method. self.queue = Queue() # The list of remote native-protocol connections. This must only be # read and modified from the event thread. self.connections = [] # The current states of all of the jets. This must only be read and # modified from the event thread. self.jet_states = [False] * 16 # True to shut down the server. This shouldn't be modified; instead, # stop() should be called, which will post an event that sets this to # True. self.shut_down = False # The server socket listening on the native protocol port self.socket = Socket() self.socket.bind(("", port)) # The Autobus service we're publishing self.service = self.bus.create_service( {"type": "sixjet", "sixjet.native_port": port}, from_py_object=AutobusService(self)) def listen_for_connections(self): # We can just infinitely loop here as run() closes the socket after # the event loop quits, which will cause an exception to be thrown here while True: s = self.socket.accept() # The connection is just a dictionary for now. We're creating it # before so that we can partial it into the input thread. connection = Connection(self, s) self.post_event({"event": "connected", "connection": connection}) connection.start() def remote_message_received(self, connection, message): self.post_event({"event": "message", "message": message}) def run(self): # Start a socket listening for connections Thread(target=self.listen_for_connections).start() # Read events and process them in a loop. while not self.shut_down: # TODO: add support for scheduled tasks here, or use separate # threads to post events when they happen. The latter would offer # a better guarantee that events will be processed when they happen # due to Python's sleep-waiting whenever using get with a timeout # (which is due to attempting to wait on a condition with a timeout # doing the aforementioned). event = self.queue.get() try: self.handle_event(event) except: traceback.print_exc() finally: self.queue.task_done() with print_exceptions: self.socket.close() def stop(self): self.post_event({"event": "stop"}) def post_event(self, event): self.queue.put(event) def handle_event(self, event): if event["event"] == "message": self.handle_message(event["message"]) elif event["event"] == "stop": self.shut_down = True elif event["event"] == "connected": self.connections.append(event["connection"]) elif event["event"] == "disconnected": self.connections.remove(event["connection"]) else: print "Warning: unrecognized event type: %r" % event def handle_message(self, message): if message["command"] == "set": for n in message["on"]: self.jet_states[n] = True for n in message["off"]: self.jet_states[n] = False self.write_jets() elif message["command"] == "clear": for n in range(len(self.jet_states)): self.jet_states[n] = False self.write_jets() else: print "Invalid message: %r" % message def set_parallel_data(self, data): """ Sets the parallel port's data pins to the specified state, which should be a number from 0 to 255, then waits a bit. """ self.write_function(data) sleep(0.0032) # 3.2 milliseconds; increase if needed def write_jets(self): """ Writes the jet states stored in jet_states to the parallel port. """ # The sixjet board is basically made up of two 74HC595 8-bit shift # registers. For those not familiar with shift registers, they're basically # a queue of bits; new bits can be pushed in at one end, and when the queue # is full, old bits will be dropped from the other end. They can then be # instructed to take the bits currently in the queue and set 8 of their # pins to those values. They're perfect for controlling things like banks # of relays from the parallel port. # To push a bit into the queue, you set the shift register's DATA pin to # 0 if you want to push a 0 and 1 if you want to push a 1. Then you set the # CLOCK pin high and then back low. # To have the shift register take the bits in the queue and set its eight # output pins to their values, you set the shift register's STROBE pin high # and then low. # On the 74HC595 shift register, pin 11 is CLOCK, pin 12 is STORBE, and pin # 15 is DATA. Googling "74HC595 datasheet" will pull up a map of which pin # numbers are which physical pins on the 74HC595. # The sixjet board has two shift registers that each control a bank of 8 # relays. The module constants DATA_A and DATA_B correspond to the data # pins of each of these shift registers. CLOCK and STROBE are connected to # both shift registers' clock and strobe pins. # So, to write out the data... # Clear the parallel port self.set_parallel_data(0) # Iterate over all the jets in reverse order. We reverse the ordering here # since the first bit written out will end up shifted to the last position # in the shift register, so we want to write the last bit first. for a, b in reversed(zip(self.jet_states[0:8], self.jet_states[8:16])): # Set lines A and B to the jets we're writing values = (DATA_A if a else 0) | (DATA_B if b else 0) self.set_parallel_data(values) # Do it an extra time just to see if it helps some issues I've been # seeing with data occasionally getting clocked in wrong self.set_parallel_data(values) # Set clock high self.set_parallel_data(values | CLOCK) # Set clock low self.set_parallel_data(values) # Set strobe high self.set_parallel_data(STROBE) # Set strobe low self.set_parallel_data(0)