"""
A Simple Server class that allows to configure a socket in a very simple way.
It is for studying purposes only.
"""

import socket
import sys


__author__ = "Facundo Victor"
__license__ = "MIT"
__email__ = "facundovt@gmail.com"


class SimpleServer(object):
    """Simple server using the socket library"""

    def __init__(self, blocking=False, connection_oriented=True):
        """
        The constructor initializes socket specifying the blocking status and
        if it must be a connection oriented socket.

        :param blocking: A flag that specifies if the socket must be blocking
        :ptype: Boolean

        :param connection_oriented: A flag that specifies if the socket must
                                    be connection oriented or not
        :ptype: Boolean
        """
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        if not blocking:
            self.sock.setblocking(0)

    def bind_and_listeen(self, host, port, max_conn=5):
        """
        Binds the socket to the "host", and prepares it to listen on "port"
        respecting a maximum of "max_connections"

        :param host: The network layer identifier of an interface
        :ptype: String or Integer (see help(socket))

        :param port: The transport layer identifier of an application
        :ptype: Integer

        :param max_conn: Number of unaccepted connections that the system will
                         allow before refusing new connections.
        :ptype: Integer
        """
        server_address = (host, port)
        self.sock.bind(server_address)
        self.sock.listen(max_conn)
        print('Socket binded to %s port %s,' % server_address + (max_conn,)



@@ -866,16 +866,49 @@
 STREAM)%0A
+        self.blocking = blocking%0A
         
@@ -960,16 +960,249 @@
 cking(0)
+%0A            # Sockets from which we expect to read%0A            self.inputs = %5Bself.sock%5D%0A            # Sockets to which we expect to write%0A            self.outputs = %5B%5D%0A        # Socket registered handlers%0A        self.handlers = %5B%5D
 %0A%0A    de
@@ -1971,11 +1971,1628 @@
 x_conn,)
-%0A%0A
+)%0A        if self.blocking:%0A            self.manage_simple_connection()%0A        else:%0A            self.manage_connections()%0A%0A    def register_handler(self, handler):%0A        %22%22%22%0A        Register a handler method to be executed on accepted connections. It%0A        must have the tuple (input: Socket, output: Socket, error: Socket) as%0A        an argument. If the handler already is registered, the method returns%0A        False.%0A%0A        :param handler: Socket event handler%0A        :ptype: Method%0A%0A        :returns: True if the handler is registered, False in other case.%0A        :rtype: Boolean%0A        %22%22%22%0A        if self.is_registered(handler):%0A            return False%0A        else:%0A            self.handlers += %5Bhandler%5D%0A            return True%0A%0A    def unregister_handlre(self, handler):%0A        %22%22%22%0A        Unregister the handler so it no longer will be executed on accepted%0A        connections.%0A%0A        :param handler: Socket event handler%0A        :ptype: Method%0A%0A        :returns: True if the handler is unregistered, False in other case.%0A        :rtype: Boolean%0A        %22%22%22%0A        try:%0A            self.handlers.remove(handler)%0A            return True%0A        except ValueError:%0A            return False%0A%0A    def is_registered(self, handler):%0A        %22%22%22%0A        Verify if the handler is registered.%0A%0A        :param handler: Socket event handler%0A        :ptype: Method%0A%0A        :returns: True if the handler is registered, False in other case.%0A        :rtype: Boolean%0A        %22%22%22%0A        try:%0A            self.handlers.index(handler)%0A            return True%0A        except ValueError:%0A            return False
 %0A

Add Handler support for socket events