Exemple #1
0
    def __listen(self):
        """
        This method is called from the connection manager when the socket is a
        server socket and should bind to the port specified.
        """
        if self.__socket or not self.__listener:
            return False

        if self.__unix_socket:
            if os.path.exists(self.__port):
                try:
                    os.unlink(self.__port)
                except:
                    self.__logger.error("Socket %s exists and cannot be " \
                                        "removed" % self.__port)
                    return False

            sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            address = (self.__port)
            to_what = "Unix Domain Socket %s" % self.__port
        else:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            address = (self.__host, self.__port)
            to_what = "TCP port %d" % self.__port

        try:
            sock.bind(address)
            sock.listen(5)
            self.__set_socket_options(sock)
        except socket.error as e:
            self.__logger.warning("Could not bind to %s: %s" \
                                  % (to_what, str(e)))
            return False
        except Exception as e:
            # Other exceptions usually mean bad settings. Try one more time but
            # do not keep on trying forever..
            self.__logger.error("Could not connect to %s: %s" \
                                % (to_what, str(e)))
            self.__giveup = 2
            return False

        self.__logger.info("Socket listening on %s initialized" % to_what)

        self.__socket = sock
        self.__fileno = self.__socket.fileno()
        self.__connected = True
        mgr = IOManager()
        mgr.register(self)
        return True
    def __listen(self):
        """
        This method is called from the connection manager when the socket is a
        server socket and should bind to the port specified.
        """
        if self.__socket or not self.__listener:
            return False

        if self.__unix_socket:
            if os.path.exists(self.__port):
                try:
                    os.unlink(self.__port)
                except:
                    self.__logger.error("Socket %s exists and cannot be " \
                                        "removed" % self.__port)
                    return False

            sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            address = (self.__port)
            to_what = "Unix Domain Socket %s" % self.__port
        else:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            address = (self.__host, self.__port)
            to_what = "TCP port %d" % self.__port

        try:
            sock.bind(address)
            sock.listen(5)
            self.__set_socket_options(sock)
        except socket.error as e:
            self.__logger.warning("Could not bind to %s: %s" \
                                  % (to_what, str(e)))
            return False
        except Exception as e:
            # Other exceptions usually mean bad settings. Try one more time but
            # do not keep on trying forever..
            self.__logger.error("Could not connect to %s: %s" \
                                % (to_what, str(e)))
            self.__giveup = 2
            return False

        self.__logger.info("Socket listening on %s initialized" % to_what)

        self.__socket = sock
        self.__fileno = self.__socket.fileno()
        self.__connected = True
        mgr = IOManager()
        mgr.register(self)
        return True
Exemple #3
0
    def __connect(self):
        """
        This method is called by the _do_attempt method when the socket is a
        connecting socket that should try to connect
        """
        if self.__socket:
            return False

        if self.__unix_socket:
            sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            address = (self.__port)
            to_what = "Unix Domain Socket %s" % self.__port
        else:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            address = (self.__host, self.__port)
            to_what = "TCP port %d" % self.__port
        try:
            sock.connect(address)
            self.__set_socket_options(sock)
        except socket.error as e:
            self.__logger.error("Could not connect to %s: %s" \
                                % (to_what, str(e)))
            return False
        except Exception as e:
            # Other exceptions mean bad settings. Try one more time but do not
            # keep on trying forever..
            self.__logger.error("Could not connect to %s: %s" \
                                % (to_what, str(e)))
            self.__giveup = 2
            return False

        self.__socket = sock
        self.__connected = True
        self.__fileno = self.__socket.fileno()

        mgr = IOManager()
        mgr.register(self)
        if not self.send_buffer_empty():
            mgr.set_writable(self, True)

        return True
    def __connect(self):
        """
        This method is called by the _do_attempt method when the socket is a
        connecting socket that should try to connect
        """
        if self.__socket:
            return False

        if self.__unix_socket:
            sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            address = (self.__port)
            to_what = "Unix Domain Socket %s" % self.__port
        else:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            address = (self.__host, self.__port)
            to_what = "TCP port %d" % self.__port
        try:
            sock.connect(address)
            self.__set_socket_options(sock)
        except socket.error as e:
            self.__logger.error("Could not connect to %s: %s" \
                                % (to_what, str(e)))
            return False
        except Exception as e:
            # Other exceptions mean bad settings. Try one more time but do not
            # keep on trying forever..
            self.__logger.error("Could not connect to %s: %s" \
                                % (to_what, str(e)))
            self.__giveup = 2
            return False

        self.__socket = sock
        self.__connected = True
        self.__fileno = self.__socket.fileno()

        mgr = IOManager()
        mgr.register(self)
        if not self.send_buffer_empty():
            mgr.set_writable(self, True)

        return True
Exemple #5
0
    def __init__(
        self,
        host="localhost",  # The host to connect to or serve
        port=49152,  # The port to connect to or serve
        giveup=5,  # Amount of reconnect attempts
        use_socket=None,  # Pass in a connected socket object to use
        retry_timeout=1,  # Timeout between connection attempts
        server=None,  # True for a server, False for clients
        use_pickle=True,  # Whether to pickle/unpickle 
        #    send/received data
        bufsize="auto",  # Number of bytes to send/receive at once
        linger=.1,  # Whether to set the SO_LINGER option
        handler=False,  # Set to true to make this a incoming 
        #    connection handler
        logger=None  # Pass in a logger to use
    ):
        """
        Initialize the socket. The parameters define the behavior of the socket.
        
        Host should be an IP address or hostname to which to connect or on which
        to listen. If the server argument is not specifically set, the hostname
        will also define whether this will be a server or client socket: if host
        is empty, it will be a server socket listening on all interfaces,
        otherwise it will be a client socket. 

        port should be the port to listen on. When the port is numeric it is
        assumed to be a TCP port. When it is a string, it will be cast to an int
        specifying a TCP port. If the conversion failed, it is assumed to be a
        Unix Socket, located in /tmp. This will raise an exception if the socket
        is trying to connect to a remove Unix Socket, which is impractical and
        defeats the purpose.

        giveup is the amount of retries performed to connect to a socket or bind
        to a port.

        use_socket can be used to pass in an already connected socket. The same
        socket options will be set on this socket as newly created ones.

        retry_timeout defines the number of seconds to wait between connection/
        binding attempts of unconnected sockets.

        server is a boolean that specifies whether this will be a server or a
        client socket. A server socket will bind and listen to a port, a client
        socket will attempt to connect to a port. The default value decides this
        automatically, based on the value of the host parameter as described
        above.

        use_pickle is a boolean specifying whether communication on this socket
        will proceed using the Pickle protocol. If set to true, all outgoing
        data will be pickled and all incoming data will be unpickled.

        bufsize specifies the amount of data to send or receive at once. The
        default is auto, meaning it will be set depending on other options. When
        the socket to use is a Unix Domain Socket, it will use 128 KiB. If it is
        a client socket connecting to a local socket, it will be a 16 KiB and if
        it is a server socket or a client socket connecting to a non-local host,
        a buffer of 8 KiB is used.

        linger is a number specifying whether the socket will be set in
        linger mode (see man page for setsockopt(2)). When in linger mode, the
        call to close on the socket will block for at most a set number of
        seconds and will then forcefully close the socket. Otherwise, the close
        call is non-blocking and the socket will get in a TIME_WAIT state, which
        effectively blocks the port for up to 4 minutes, possibly resulting in
        'Port already bound' messages. If the linger parameter is 0, LINGER will
        not be used; otherwise this is the amount of seconds to set.

        handler can be set to True to activate incoming connection handler 
        behavior. This basically makes sure that no reconnetion attempt is 
        performed when the connection is closed by the other end.
        """

        self.__socket = None
        self.__fileno = None
        self.__client_sockets = []
        self.__connected = False
        self.__listener = False
        self.__handler = handler
        self.__use_pickle = use_pickle

        self.__send_lock = threading.RLock()
        self.__receive_lock = threading.RLock()
        self.__receive_buffer = []
        self.__recv_buffer = ""
        self.__send_buffer = []
        self.__send_buffer_ids = set([])
        self.__buffer_start_pos = 0
        self.__send_id = 0

        self.__set_port(host, port)

        self.__set_buffer_size(bufsize)
        self.__linger = float(linger)
        self.__total_bytes = 0

        self.__log_input = False
        self.__log_output = False

        if server is None and self.__host == "":
            self.__listener = True
        else:
            self.__listener = server

        if logger:
            self.__logger = logger
        else:
            self.__logger = logging.getLogger('Borg.Brain.Util.ThreadedSocket')

        self.__logger.addHandler(nullhandler.NullHandler())

        self.__last_attempt = 0
        self.__timeout = retry_timeout
        self.__giveup = giveup
        self.__attempt = 0

        if use_socket:
            self.__socket = use_socket
            self.__fileno = self.__socket.fileno()
            self.__port = port
            self.__connected = True
            self.__set_socket_options(self.__socket)
            mgr = IOManager()
            mgr.register(self)
        else:
            mgr = IOManager()
            mgr.register_unconnected(self)
    def __init__(self,
                 host="localhost", # The host to connect to or serve
                 port=49152,       # The port to connect to or serve
                 giveup=5,         # Amount of reconnect attempts
                 use_socket=None,  # Pass in a connected socket object to use
                 retry_timeout=1,  # Timeout between connection attempts
                 server=None,      # True for a server, False for clients
                 use_pickle=True,  # Whether to pickle/unpickle 
                                   #    send/received data
                 bufsize="auto",   # Number of bytes to send/receive at once
                 linger=.1,        # Whether to set the SO_LINGER option
                 handler=False,    # Set to true to make this a incoming 
                                   #    connection handler
                 logger=None       # Pass in a logger to use
                ):
        """
        Initialize the socket. The parameters define the behavior of the socket.
        
        Host should be an IP address or hostname to which to connect or on which
        to listen. If the server argument is not specifically set, the hostname
        will also define whether this will be a server or client socket: if host
        is empty, it will be a server socket listening on all interfaces,
        otherwise it will be a client socket. 

        port should be the port to listen on. When the port is numeric it is
        assumed to be a TCP port. When it is a string, it will be cast to an int
        specifying a TCP port. If the conversion failed, it is assumed to be a
        Unix Socket, located in /tmp. This will raise an exception if the socket
        is trying to connect to a remove Unix Socket, which is impractical and
        defeats the purpose.

        giveup is the amount of retries performed to connect to a socket or bind
        to a port.

        use_socket can be used to pass in an already connected socket. The same
        socket options will be set on this socket as newly created ones.

        retry_timeout defines the number of seconds to wait between connection/
        binding attempts of unconnected sockets.

        server is a boolean that specifies whether this will be a server or a
        client socket. A server socket will bind and listen to a port, a client
        socket will attempt to connect to a port. The default value decides this
        automatically, based on the value of the host parameter as described
        above.

        use_pickle is a boolean specifying whether communication on this socket
        will proceed using the Pickle protocol. If set to true, all outgoing
        data will be pickled and all incoming data will be unpickled.

        bufsize specifies the amount of data to send or receive at once. The
        default is auto, meaning it will be set depending on other options. When
        the socket to use is a Unix Domain Socket, it will use 128 KiB. If it is
        a client socket connecting to a local socket, it will be a 16 KiB and if
        it is a server socket or a client socket connecting to a non-local host,
        a buffer of 8 KiB is used.

        linger is a number specifying whether the socket will be set in
        linger mode (see man page for setsockopt(2)). When in linger mode, the
        call to close on the socket will block for at most a set number of
        seconds and will then forcefully close the socket. Otherwise, the close
        call is non-blocking and the socket will get in a TIME_WAIT state, which
        effectively blocks the port for up to 4 minutes, possibly resulting in
        'Port already bound' messages. If the linger parameter is 0, LINGER will
        not be used; otherwise this is the amount of seconds to set.

        handler can be set to True to activate incoming connection handler 
        behavior. This basically makes sure that no reconnetion attempt is 
        performed when the connection is closed by the other end.
        """
        self.__socket = None
        self.__fileno = None
        self.__client_sockets = []
        self.__connected = False
        self.__listener = False
        self.__handler = handler
        self.__use_pickle = use_pickle

        self.__send_lock = threading.RLock()
        self.__receive_lock = threading.RLock()
        self.__receive_buffer = []
        self.__recv_buffer = ""
        self.__send_buffer = []
        self.__send_buffer_ids = set([])
        self.__buffer_start_pos = 0
        self.__send_id = 0

        self.__set_port(host, port)

        self.__set_buffer_size(bufsize)
        self.__linger = float(linger)
        self.__total_bytes = 0

        self.__log_input = False
        self.__log_output = False

        if server is None and self.__host == "":
            self.__listener = True
        else:
            self.__listener = server

        if logger:
            self.__logger = logger
        else:
            self.__logger = logging.getLogger('Borg.Brain.Util.ThreadedSocket')

        self.__logger.addHandler(nullhandler.NullHandler())

        self.__last_attempt = 0
        self.__timeout = retry_timeout
        self.__giveup = giveup
        self.__attempt = 0

        if use_socket:
            self.__socket = use_socket
            self.__fileno = self.__socket.fileno()
            self.__port = port
            self.__connected = True
            self.__set_socket_options(self.__socket)
            mgr = IOManager()
            mgr.register(self)
        else:
            mgr = IOManager()
            mgr.register_unconnected(self)