Example #1
0
class ClientManager(object):
    def __init__(self):
        self.socket_handler = SocketHandler()
        self.gui_handler = GuiHandler()
        self.http_handler = HttpHandler()
        self.user_button = {
            "send integer": self._wait_until_user_feeds_operation
        }
        self.shared_value = "1"
        self.operation_msg = ""
        self.operation_log = ""
        self.file_handler = None
        pass

    def perform_client_application(self):  #
        """
        Main function to perform client application.
        Application sends integer to server application and expects to wait or sleep for the number of seconds specified by integer.

        Function performs following tasks
        1) Establishes socket connection with client
        2) Initialize gui. Gui contains 2 buttons
            1 button to quit the application.
            other to generate a random integer between 5 to 15 and send it to server

        :return: None
        """
        self._establish_socket_connection()
        _thread.start_new_thread(
            self._send_client_name_and_operations_to_server, ())
        self.gui_handler.init_client_auth_gui(
            quit_button_command=self._terminate_pgm,
            user_buttons_dict=self.user_button)

    def _send_client_name_and_operations_to_server(self):
        """
        Function to send client name and random numbers to server.

        Function performs following steps:
        1) Gets client name from user
        2) Generates random number and sends it to server.

        :return: None
        """
        time.sleep(1)
        try:
            self._get_client_name_from_user_and_send_to_server()  #
            self.file_handler = open(self.client_name + ".txt", "w+")
            self.gui_handler.modify_text_in_frames_for_gui(
                "info :: Client connected to Server")  #
            self._get_operations_from_user_and_send_it_to_client()
        except:
            err_message = "info :: Error in sending message to Server.\n Message might not have reached Server"
            self.gui_handler.modify_text_in_frames_for_gui(err_message)

    def _get_initial_value_from_server(self):
        """
        Function to receive shared value from server.
        Fucntion receives json string containing shared value.
        :return:
        """
        message = self.socket_handler.receive_message_from_server()
        message_dict = loads(message)
        return str(message_dict["shared_value"])

    def _wait_until_user_feeds_operation(self):
        """
        Wait for user to input operations.
        Function performs the following steps.
        1)Execute while loop until user has given input in text box.
        :return:
        """
        self.gui_handler.text_box_value = ""
        while self.gui_handler.text_box_value == "":
            pass
        self.operation_msg = self.gui_handler.text_box_value
        self.file_handler.write("{}\n".format(self.operation_msg))
        self.gui_handler.modify_text_in_frames_for_gui(self.operation_msg)

    def _perform_operations_on_values(self):
        """
        Function to perform user provided operations on shared value.
        Eval function is used to perform operation on shared value.

        :return:
        """
        try:
            eval_statement = "{}{}".format(self.shared_value.strip(),
                                           self.operation_msg.strip())
            self.gui_handler.modify_text_in_frames_for_gui(
                "eval_statement {}".format(eval_statement))
            result = str(eval(eval_statement))
            self.gui_handler.modify_text_in_frames_for_gui(
                "Operation {} result ::\n{}".format(eval_statement, result))
            return result
        except Exception as err:
            self.gui_handler.modify_text_in_frames_for_gui(
                "Operation syntax error. Invalid operation")
            self._wait_until_user_feeds_operation()
            self._perform_operations_on_values()

    def _update_result_value_to_server(self, result):
        """
        Function to send  operation result and operations to server.

        Function performs the following:
        1)create json string containing operation and operation result
        2)send it to server via socket.

        :param result:
        :return:
        """
        message_dict = {
            "operation": self.operation_msg.strip(),
            "operation_result": result
        }
        self.socket_handler.send_message_to_server(dumps(message_dict))

    def _get_operations_from_user_and_send_it_to_client(self):
        """
        Function to get operations from user and perform it on initial value of client or server provided value
        Function performs the following tasks:
        1)Get shared value from server if that value is not client's initial value
        2)Wait until user provides operation in GUI
        3)Perform that operation on shared value
        4)Update the value and operation to server.
        :return:
        """
        while (True):
            shared_value = self._get_initial_value_from_server()
            if shared_value == self.shared_value:
                self.gui_handler.modify_text_in_frames_for_gui(
                    "Init value is 1")
            else:
                self.shared_value = shared_value
                self.gui_handler.modify_text_in_frames_for_gui(
                    "Shared value received from server :: {}".format(
                        shared_value))
            self._wait_until_user_feeds_operation()
            result = self._perform_operations_on_values()
            self._update_result_value_to_server(result)

    def _get_operation_from_user(self):
        """
        Function to get operations from user.

        :return: integer between 5 to 15
        """
        self.operation_msg = self.gui_handler.text_box_value

    def _establish_socket_connection(self):
        """
         function to establish socket connection and connects with server.

         Function performs the following steps.
         1) Create client socket
         2) Connect to server

        :return: None
        """
        self.socket_handler.create_client_socket()
        self.socket_handler.connect_to_server()

    def _terminate_pgm(self):
        """
        Function to terminate the application. Called when quit button on gui.
        Function performs the following steps.
        1)Send message that Client is exiting.
        2)Terminate the client socket.
        3)Exit application
        :return: None
        """
        try:
            message = {"end_connection": True}
            self.socket_handler.send_message_to_server(dumps(message))
        except:
            print("Server socket terminated...")
        self.socket_handler.terminate_socket()
        exit(0)

    def _get_client_name_from_user_and_send_to_server(self):
        """
        Function to send to client name to server.

        Function performs the following steps:

        1)Get client name from user
        2)Encode name in http format
        3)Send the encoded message to server

        :return:
        """
        self.gui_handler.modify_text_in_frames_for_gui(
            "Enter client name in text box.")
        while self.gui_handler.text_box_value is None:
            pass
        self.client_name = self.gui_handler.text_box_value
        message_dict = {"client_name": self.client_name}
        self.socket_handler.send_message_to_server(dumps(message_dict))
Example #2
0
class ServerManager(object):
    def __init__(self):
        self.gui_handler = GuiHandler()
        self.socket_handler = SocketHandler()
        self.threads = list()
        self.http_handler = HttpHandler()
        pass

    def _accept_client_requests(self):
        """
        Function to accept requests of client.

        Performs the following steps:
        1)Accept a client connection.
        2)Assign a thread to satisfy the requests of client.
        3)perform step 1 & 2 to accept other client requests.

        :return: None
        """
        while True:
            client_obj, client_addr = self.socket_handler.accept_incoming_client_request(
            )
            if client_obj:
                _thread.start_new_thread(self._handle_client_requests,
                                         (client_obj, client_addr))

    def perform_server_application(self):
        """
        Central function that runs the server application

        Function performs the following steps:
        1) create a working socket
        2)start new thread that manages incoming client requests.
        3)start GUI for the application with the parent thread(required for tkinter library)

        :return:None
        """
        self._establish_working_socket()
        time.sleep(2)
        _thread.start_new_thread(self._accept_client_requests, ())
        self.gui_handler.initialize_gui()

    def _establish_working_socket(self):
        """
        Function to establish to sockets.

        Function performs the following steps:
        1)create a working socket and bind it to server ip and specified port.
        2)Make server listen with its new socket for incoming client requests.

        :return: None
        """
        self.socket_handler.create_server_socket()
        self.socket_handler.listen_to_incoming_client_request(request_queue=5)

    def _handle_client_requests(self, client_obj, client_addr):
        """
        Function to handle client requests. The client sends number of seconds the server has to wait or sleep for the
        client.

        Function performs the following steps:
        1) get request message  from client.
        2) if message contains value 900 then connection with client is terminated.
        3) if value is between 5 to 15, then server sleeps for time specified in value.


        :param client_obj: client object
        :param client_addr: tuple containing client ip and port number.
        :return: None
        """
        self.gui_handler.modify_text_in_frames_for_gui(
            "info :: Server connected to client :: {}".format(
                str(client_addr)))
        client_name = self._get_client_name(client_obj, client_addr)
        while True:
            sleep_time = self._get_sleep_time_from_client(
                client_obj, client_addr)
            if "900" in sleep_time:
                self._terminate_socket_connection_with_client(
                    client_obj, client_addr, client_name)
                break
            else:
                self._perform_sleep_operation_for_client(
                    int(sleep_time), client_obj, client_addr, client_name)

    def _decode_http_message(self, message):
        """

        :param message:
        :return:
        """
        return message

    def _terminate_socket_connection_with_client(self,
                                                 client_obj,
                                                 client_addr,
                                                 client_name=""):
        """
        Function to terminate connection with client.

        :param client_obj: client object
        :param client_addr: tuple containing client ip and client port number
        :return: None
        """
        self.gui_handler.modify_text_in_frames_for_gui(
            "info :: Client {} has terminated connection".format(
                str(client_name) + str(client_addr)))
        self.socket_handler.terminate_client_connection(
            client_obj, client_addr)

    def _get_sleep_time_from_client(self, client_obj, client_addr):
        """
        Function to get sleep time from client.

        Function performs the following steps:
        1)get http request message from client
        2)decode http request message and get time value.

        :param client_obj:
        :param client_addr:
        :param client_name:
        :return: integer value specifying the number of seconds server has to sleep.
        """
        message = self.socket_handler.receive_message_from_client(
            client_obj, client_addr)
        decoded_message = self.http_handler.http_request_decode(message)
        return decoded_message[1]

    def _perform_sleep_operation_for_client(self, sleep_time, client_obj,
                                            client_addr, client_name):
        """
        Function to make server sleep for value specified by client.

        :param sleep_time: integer specifying the number of seconds server has to sleep for.
        :param client_obj: client object
        :param client_addr: tuple containing client ip and client port number.
        :return:
        """
        self.gui_handler.modify_text_in_frames_for_gui(
            "info :: received int {0} from client {1}.\nSleeping for {0} sec".
            format(str(sleep_time),
                   str(client_name) + str(client_addr)))
        time.sleep(sleep_time)
        self.gui_handler.modify_text_in_frames_for_gui(
            "info :: Slept {}sec for client {}.".format(
                str(sleep_time),
                str(client_name) + str(client_addr)))
        decoded_message = self.http_handler.http_response_encode(
            "Slept {}sec for client {}.".format(
                str(sleep_time),
                str(client_name) + str(client_addr)))
        self.gui_handler.modify_text_in_frames_for_gui(
            "Sending  message to client {}\n<<\n{}\n>>.".format(
                str(client_name) + str(client_addr), decoded_message))
        self.socket_handler.send_message_to_client(decoded_message, client_obj,
                                                   client_addr)

    def _get_client_name(self, client_obj, client_addr):
        """
        Function to get client name from client.

        Function performs following steps:

        1)Get http request message that contains the name of client
        2)Decode the message to get client name.

        :param client_obj: Client object.
        :param client_addr: tuple containing client ip string and client port integer number.
        :return: string containing client name
        """
        message = self.socket_handler.receive_message_from_client(
            client_obj, client_addr)
        decoded_message = self.http_handler.http_request_decode(message)
        print("client name :: {}".format(str(decoded_message)))
        if "900" in decoded_message[1]:
            self._terminate_socket_connection_with_client(
                client_obj, client_addr)
        self.gui_handler.modify_text_in_frames_for_gui(
            "info :: connected to {}{}".format(decoded_message[1],
                                               str(client_addr)))
        return decoded_message[1]
Example #3
0
class ServerManager(object):
    def __init__(self):
        self.ongoing_clients = list()
        self.token = 0
        self.gui_handler = GuiHandler()
        self.socket_handler = SocketHandler()
        self.threads = list()
        self.http_handler = HttpHandler()
        self.shared_value = 1
        pass

    def _accept_client_requests(self):
        """
        Function to accept requests of client.

        Performs the following steps:
        1)Accept a client connection.
        2)Assign a thread to satisfy the requests of client.
        3)perform step 1 & 2 to accept other client requests.

        :return: None
        """
        while True:
            client_obj, client_addr = self.socket_handler.accept_incoming_client_request(
            )
            if client_obj:
                _thread.start_new_thread(self._handle_client_requests,
                                         (client_obj, client_addr))

    def perform_server_application(self):
        """
        Central function that runs the server application

        Function performs the following steps:
        1) create a working socket
        2)start new thread that manages incoming client requests.
        3)start GUI for the application with the parent thread(required for tkinter library)

        :return:None
        """
        self._establish_working_socket()
        time.sleep(2)
        _thread.start_new_thread(self._accept_client_requests, ())
        self.gui_handler.initialize_gui()

    def _establish_working_socket(self):
        """
        Function to establish to sockets.

        Function performs the following steps:
        1)create a working socket and bind it to server ip and specified port.
        2)Make server listen with its new socket for incoming client requests.

        :return: None
        """
        self.socket_handler.create_server_socket()
        self.socket_handler.listen_to_incoming_client_request(request_queue=5)

    def _handle_client_requests(self, client_obj, client_addr):
        """
        Function to handle client requests. The client sends number of seconds the server has to wait or sleep for the
        client.

        Function performs the following steps:
        1) get request message  from client.
        2) if message contains value end_connection then connection with client is terminated.
        3) obtain operation from client from client.
        4)Perform it on server value
        5)Send shared value back top clients

        :param client_obj: client object
        :param client_addr: tuple containing client ip and port number.
        :return: None
        """
        self.gui_handler.modify_text_in_frames_for_gui(
            "info :: Server connected to client :: {}".format(
                str(client_addr)))
        client_name = self._get_client_name(client_obj, client_addr)
        while True:
            operation_dict = self._get_operation_from_client(
                client_obj, client_addr)
            if "end_connection" in operation_dict:
                self._terminate_socket_connection_with_client(
                    client_obj, client_addr, client_name)
                break
            else:
                self._obtain_shared_value_from_client(operation_dict,
                                                      client_obj, client_addr,
                                                      client_name)
                self._send_new_shared_value_to_client(client_obj, client_addr,
                                                      client_name)

    def _send_new_shared_value_to_client(self, client_obj, client_addr,
                                         client_name):
        message = {"shared_value": self.shared_value}
        self.socket_handler.send_message_to_client(dumps(message), client_obj,
                                                   client_addr)

    def _obtain_shared_value_from_client(self, operation_dict, client_obj,
                                         client_addr, client_name):
        old_shared_value = self.shared_value
        client_result = operation_dict["operation_result"]
        operation = operation_dict["operation"]
        self.shared_value = str(
            eval("{}{}".format(old_shared_value, operation)))
        self.gui_handler.modify_text_in_frames_for_gui(
            "Received operations {} from client {}\nclient result :: {} ".
            format(operation,
                   str(client_name) + str(client_addr), client_result))
        self.gui_handler.modify_text_in_frames_for_gui(
            "Shared value updated from {} to {} by performing {}".format(
                old_shared_value, self.shared_value, operation))

    def _terminate_socket_connection_with_client(self,
                                                 client_obj,
                                                 client_addr,
                                                 client_name=""):
        """
            Function to terminate connection with client.

            :param client_obj: client object
            :param client_addr: tuple containing client ip and client port number
            :return: None
            """
        self.gui_handler.modify_text_in_frames_for_gui(
            "info :: Client {} has terminated connection".format(
                str(client_name) + str(client_addr)))
        self.socket_handler.terminate_client_connection(
            client_obj, client_addr)

    def _get_operation_from_client(self, client_obj, client_addr):
        """
        Function to get sleep time from client.

        Function performs the following steps:
        1)get http request message from client
        2)decode http request message and get time value.

        :param client_obj:
        :param client_addr:
        :param client_name:
        :return: integer value specifying the number of seconds server has to sleep.
        """
        message = self.socket_handler.receive_message_from_client(
            client_obj, client_addr)
        message = loads(message)
        return message

    def _get_client_name(self, client_obj, client_addr):
        """
            Function to get client name from client.

            Function performs following steps:

            1)Get http request message that contains the name of client
            2)Decode the message to get client name.

            :param client_obj: Client object.
            :param client_addr: tuple containing client ip string and client port integer number.
            :return: string containing client name
        """
        message = self.socket_handler.receive_message_from_client(
            client_obj, client_addr)
        message = loads(message)
        if "end_connection" in message:
            self._terminate_socket_connection_with_client(
                client_obj, client_addr)
        self.gui_handler.modify_text_in_frames_for_gui(
            "info :: connected to {}{}".format(str(message["client_name"]),
                                               str(client_addr)))
        self.socket_handler.send_message_to_client(
            dumps({"shared_value": self.shared_value}), client_obj,
            client_addr)
        return message["client_name"]
Example #4
0
class ClientManager(object):
    def __init__(self):
        self.socket_handler = SocketHandler()
        self.gui_handler = GuiHandler()
        self.http_handler = HttpHandler()
        self.user_button = {"send integer": self._generate_random_number}
        self.rand_int = None
        pass

    def perform_client_application(self):
        """
        Main function to perform client application.
        Application sends integer to server application and expects to wait or sleep for the number of seconds specified by integer.

        Function performs following tasks
        1) Establishes socket connection with client
        2) Initialize gui. Gui contains 2 buttons
            1 button to quit the application.
            other to generate a random integer between 5 to 15 and send it to server

        :return: None
        """
        self._establish_socket_connection()
        _thread.start_new_thread(
            self._send_client_name_and_random_number_to_client, ())
        self.gui_handler.init_client_auth_gui(
            quit_button_command=self._terminate_pgm,
            user_buttons_dict=self.user_button)

    def _send_client_name_and_random_number_to_client(self):
        """
        Function to send client name and random numbers to server.

        Function performs following steps:
        1) Gets client name from user
        2) Generates random number and sends it to server.

        :return: None
        """
        try:
            self._get_client_name_from_user_and_send_to_server()
            self.gui_handler.modify_text_in_frames_for_gui(
                "info :: Client connected to Server")
            self._get_number_from_user_and_send_to_server()
        except:
            err_message = "info :: Error in sending message to Server.\n Message might not have reached Server"
            self.gui_handler.modify_text_in_frames_for_gui(err_message)

    def _communicate_with_server(self, message, sleep_int):
        """
        Function to communicate with server.

        performs the following steps.
        1) send http encoded message (integer) to server.
        2) Receive response message from server.
        3) Decode the message and get the original message
        3) display that message on gui

        :param message: string containing integer between 5 to 15 which is encoded in http.
        :return: None
        """
        self.socket_handler.send_message_to_server(message)
        print("client sleeping")
        time.sleep(sleep_int)
        message = self.socket_handler.receive_message_from_server()
        message = self.http_handler.http_response_decode(message)
        print(message)
        self.gui_handler.modify_text_in_frames_for_gui(
            "Server response :: {}".format(message))

    def _generate_random_number(self):
        """
        Function to generate random integer between 5 to 15

        :return: integer between 5 to 15
        """
        self.rand_int = randint(5, 15)

    def _establish_socket_connection(self):
        """
         function to establish socket connection and connects with server.

         Function performs the following steps.
         1) Create client socket
         2) Connect to server

        :return: None
        """
        self.socket_handler.create_client_socket()
        self.socket_handler.connect_to_server()

    def _terminate_pgm(self):
        """
        Function to terminate the application. Called when quit button on gui.
        Function performs the following steps.
        1)Send message that Client is exiting.
        2)Terminate the client socket.
        3)Exit application
        :return: None
        """
        try:
            encoded_message = self.http_handler.http_request_encode(
                "sleep_time", 900)
            self.socket_handler.send_message_to_server(encoded_message)
        except:
            print("Server socket terminated...")
        self.socket_handler.terminate_socket()
        exit(0)

    def _encode_number_with_http(self, sleep_int):
        """
        Function to encode message to http.
        :param sleep_int: Integer that is to encoded to http.
        :return: string containing http encoded message.
        """
        return str(sleep_int)

    def _get_client_name_from_user_and_send_to_server(self):
        """
        Function to send to client name to server.

        Function performs the following steps:

        1)Get client name from user
        2)Encode name in http format
        3)Send the encoded message to server

        :return:
        """

        while self.gui_handler.text_box_value is None:
            pass
        encoded_message = self.http_handler.http_request_encode(
            "client_name", self.gui_handler.text_box_value)
        self.socket_handler.send_message_to_server(encoded_message)

    def _get_number_from_user_and_send_to_server(self):
        """
                Function to generate an integer, encode it in http, and send it to server.

                Function performs the following steps
                1) Generate random integer 'n' between 5 to 15.
                2) Encode 'n' in http.
                3) Send http request message to server. Wait for it sleep 'n' seconds and get response from server.

                :return: None
        """
        while True:
            while self.rand_int is None:
                pass
            message = self.http_handler.http_request_encode(
                "sleep_int", self.rand_int)
            self.gui_handler.modify_text_in_frames_for_gui(
                "info :: Sending message to server ::\n<<\n{}\n>>".format(
                    str(message)))
            self._communicate_with_server(message, self.rand_int)
            self.rand_int = None