Example #1
0
    def new_reunion_packet(type, source_address, nodes_array):
        """
        :param type: Reunion Hello (REQ) or Reunion Hello Back (RES)
        :param source_address: IP/Port address of the packet sender.
        :param nodes_array: [(ip0, port0), (ip1, port1), ...] It is the path to the 'destination'.

        :type type: str
        :type source_address: tuple
        :type nodes_array: list

        :return New reunion packet.
        :rtype Packet
        """

        body = ""
        body += type
        body += str(len(nodes_array)).zfill(2)
        if type == "REQ":
            for i in range(len(nodes_array)):
                body += Node.parse_ip(nodes_array[i][0])
                body += Node.parse_port(nodes_array[i][1])
        else:
            for i in range(len(nodes_array) - 1, -1, -1):
                body += Node.parse_ip(nodes_array[i][0])
                body += Node.parse_port(nodes_array[i][1])
        return Packet(None, PacketFactory.version, Type.reunion,
                      source_address[0], source_address[1], body)
Example #2
0
    def __init__(self, ip, port):
        """
        The Stream object constructor.

        Code design suggestion:
            1. Make a separate Thread for your TCPServer and start immediately.


        :param ip: 15 characters
        :param port: 5 characters
        """

        ip = Node.parse_ip(ip)
        port = Node.parse_port(port)

        self._server_in_buf = []

        def cb(ip, queue, data):
            queue.put(bytes('ACK', 'utf8'))
            # self.messages_dic.update({ip: self.messages_dic.get(ip).append(data)})
            self._server_in_buf.append(data)

        print("Binding server: ", ip, ": ", port)
        self._server = TCPServer(ip, int(port), cb)
        tcpserver_thread = threading.Thread(target=self._server.run)
        # self._server.run()
        tcpserver_thread.start()
        self.nodes = []
        self.ip = ip
        self.port = port
Example #3
0
    def __init__(self, ip, port):
        """
		The Stream object constructor.

		Code design suggestion:
			1. Make a separate Thread for your TCPServer and start immediately.


		:param ip: 15 characters
		:param port: 5 characters
		"""

        ip = Node.parse_ip(ip)
        port = Node.parse_port(port)
        self.nodes = {}

        self._server_in_buf = []

        def callback(address, queue, data):
            """
			The callback function will run when a new data received from server_buffer.

			:param address: Source address.
			:param queue: Response queue.
			:param data: The data received from the socket.
			:return:
			"""
            queue.put(bytes('ACK', 'utf8'))
            self._server_in_buf.append(data)

        self.tcp_server = TCPServer(ip, int(port), read_callback=callback)
        t = threading.Thread(target=self.tcp_server.run)
        t.start()
Example #4
0
    def get_server_address(self):
        """

        :return: Our TCPServer address
        :rtype: tuple
        """
        return Node.parse_ip(self._server.ip), Node.parse_port(
            self._server.port)
Example #5
0
 def parse_reunion_packet_body(body):
     body = str(body)
     numEntry = int(body[3:5])
     body = body[5:]
     result = []
     for i in range(0, numEntry):
         result.append((Node.parse_ip(body[20 * i:20 * i + 15]),
                        Node.parse_port(body[20 * i + 15:20 * i + 20])))
     return result
Example #6
0
    def __init__(self, server_ip, server_port, is_root, ui, root_address=None):
        """
        The Peer object constructor.

        Code design suggestions:
            1. Initialise a Stream object for our Peer.
            2. Initialise a PacketFactory object.
            3. Initialise our UserInterface for interaction with user commandline.
            4. Initialise a Thread for handling reunion daemon.

        Warnings:
            1. For root Peer, we need a NetworkGraph object.
            2. In root Peer, start reunion daemon as soon as possible.
            3. In client Peer, we need to connect to the root of the network, Don't forget to set this connection
               as a register_connection.


        :param server_ip: Server IP address for this Peer that should be pass to Stream.
        :param server_port: Server Port address for this Peer that should be pass to Stream.
        :param is_root: Specify that is this Peer root or not.
        :param root_address: Root IP/Port address if we are a client.

        :type server_ip: str
        :type server_port: int
        :type is_root: bool
        :type root_address: tuple
        """
        super().__init__()
        self.ui_buffer = queue.Queue()
        self.stream = Stream(server_ip, server_port, ui)
        self.ip = Node.parse_ip(server_ip)
        self.port = Node.parse_port(str(server_port))

        self.address = (self.ip, int(self.port))
        self.setDaemon(True)
        self.ui = ui
        self.is_root = is_root
        self.root_address = self.address
        if not is_root:
            self.root_address = root_address
        self.children = []
        self.is_reunion_running = False
        self.parent = None
        self.is_connected = False
        # self.reunion_timer = ReunionTimer(self)
        self.graph = NetworkGraph(GraphNode(self.root_address))
        if not self.is_root:
            print('making the shit')
            self.stream.add_node(self.root_address, True)

        self.r_h_b_received = True
        self.since_last = 0
        self.timer = Timer(self)
        self.timer.start()
        self.stop = False
Example #7
0
 def make_header(source_address, type, length):
     port = Node.parse_port(source_address[1])
     ip = Node.parse_ip(source_address[0])
     ip = ip.split('.')
     result = bytes([0])
     result = result + bytes([1])
     result = result + type.to_bytes(2, byteorder='big')
     result = result + length.to_bytes(4, byteorder='big')
     for a in ip:
         result = result + int(a).to_bytes(2, byteorder='big')
     result = result + int(port).to_bytes(4, byteorder='big')
     return result
     pass
Example #8
0
    def __check_registered(self, source_address):
        """
        If the Peer is the root of the network we need to find that is a node registered or not.

        :param source_address: Unknown IP/Port address.
        :type source_address: tuple

        :return:
        """
        if self.registered_peers is not None:
            if str(
                (Node.parse_ip(source_address[0]),
                 Node.parse_port(source_address[1]))) in self.registered_peers:
                return True
            return False
Example #9
0
    def new_reunion_packet(type, source_address, nodes_array):
        """
        :param type: Reunion Hello (REQ) or Reunion Hello Back (RES)
        :param source_address: IP/Port address of the packet sender.
        :param nodes_array: [(ip0, port0), (ip1, port1), ...] It is the path to the 'destination'.

        :type type: str
        :type source_address: tuple
        :type nodes_array: list

        :return New reunion packet.
        :rtype Packet
        """
        body = bytes(type, 'UTF-8') + bytes(str(len(nodes_array)),
                                            'UTF-8').zfill(2)
        for node in nodes_array:
            body += bytes(Node.parse_ip(node[0]), 'UTF-8') + bytes(
                Node.parse_port(node[1]), 'UTF-8')
        return PacketFactory.make_header(source_address, 5, len(body)) + body
        pass
Example #10
0
    def get_node_by_server(self, ip, port):
        """

        Will find the node that has IP/Port address of input.

        Warnings:
            1. Before comparing the address parse it to a standard format with Node.parse_### functions.

        :param ip: input address IP
        :param port: input address Port

        :return: The node that input address.
        :rtype: Node
        """
        try:
            return self.nodes[str((Node.parse_ip(ip), Node.parse_port(port)))]
        except KeyError:
            print('get node by server, could not find node')

        return None
Example #11
0
    def get_node_by_server(self, ip, port):
        """

        Will find the node that has IP/Port address of input.

        Warnings:
            1. Before comparing the address parse it to a standard format with Node.parse_### functions.

        :param ip: input address IP
        :param port: input address Port

        :return: The node that input address.
        :rtype: Node
        """
        port = Node.parse_port(port)
        ip = Node.parse_ip(ip)
        for nd in self.nodes:
            if nd.get_server_address()[0] == ip and nd.get_server_address(
            )[1] == port:
                return nd
Example #12
0
    def get_node_by_server(self, ip, port):
        """

        Will find the node that has IP/Port address of input.

        Warnings:
            1. Before comparing the address parse it to a standard format with Node.parse_### functions.

        :param ip: input address IP
        :param port: input address Port

        :return: The node that input address.
        :rtype: Node
        """
        ip = Node.parse_ip(ip)
        port = Node.parse_port(port)
        for node in self.nodes_list:
            if node.server_ip == ip and node.server_port == port:
                return node
        return None
Example #13
0
    def add_node(self, server_address, set_register_connection=False):
        """
        Will add new a node to our Stream.

        :param server_address: New node TCPServer address.
        :param set_register_connection: Shows that is this connection a register_connection or not.

        :type server_address: tuple
        :type set_register_connection: bool

        :return:
        """
        try:
            self.nodes.append(Node((Node.parse_ip(server_address[0]), int(Node.parse_port(server_address[1]))), False,
                               set_register_connection))
            return True
        except:
            self.ui.display_message('Could not Establish Connection!')
            return False
        pass
Example #14
0
    def __init__(self, ip, port, ui):
        """
        The Stream object constructor.

        Code design suggestion:
            1. Make a separate Thread for your TCPServer and start immediately.


        :param ip: 15 characters
        :param port: 5 characters

        """
        self.ip = Node.parse_ip(ip)
        self.port = int(Node.parse_port(port))
        self.server = TCPServer(self.ip, self.port, self.callback, 1000, 2048)
        self.server.start()
        self._server_in_buf = []
        self.nodes = []
        self.out_buffer = []
        self.ui = ui
Example #15
0
    def new_advertise_packet(type, source_server_address, neighbour=None):
        """
        :param type: Type of Advertise packet
        :param source_server_address Server address of the packet sender.
        :param neighbour: The neighbour for advertise response packet; The format is like ('192.168.001.001', '05335').

        :type type: str
        :type source_server_address: tuple
        :type neighbour: tuple

        :return New advertise packet.
        :rtype Packet

        """
        body = ""
        body += type
        if type == "RES":
            body += Node.parse_ip(neighbour[0])
            body += Node.parse_port(neighbour[1])
        return Packet(None, PacketFactory.version, Type.advertise,
                      source_server_address[0], source_server_address[1], body)
Example #16
0
    def __init__(self, ip, port):
        """
        The Stream object constructor.

        Code design suggestion:
            1. Make a separate Thread for your TCPServer and start immediately.


        :param ip: 15 characters
        :param port: 5 characters
        """

        self.ip = Node.parse_ip(ip)
        self.port = Node.parse_port(port)

        self._server_in_buf = []

        self.nodes = []
        self.nodes_parent_index = 1

        def callback(address, queue, data):
            """
            The callback function will run when a new data received from server_buffer.

            :param address: Source address.
            :param queue: Response queue.
            :param data: The data received from the socket.
            :return:
            """
            # print(data)
            queue.put(bytes('ACK', 'utf8'))
            self._server_in_buf.append(data)
            # print(self._server_in_buf)

        tcp_server = TCPServer(self.ip, port, callback)

        # creating thread
        t1 = threading.Thread(target=tcp_server.run)
        # starting thread 2
        t1.start()
Example #17
0
    def new_register_packet(type, source_server_address, address=(None, None)):
        """
        :param type: Type of Register packet
        :param source_server_address: Server address of the packet sender.
        :param address: If 'type' is 'request' we need an address; The format is like ('192.168.001.001', '05335').

        :type type: str
        :type source_server_address: tuple
        :type address: tuple

        :return New Register packet.
        :rtype Packet

        """
        body = ""
        body += type
        if type == "REQ":
            body += Node.parse_ip(address[0])
            body += Node.parse_port(address[1])
        else:
            body += "ACK"
        return Packet(None, PacketFactory.version, Type.register,
                      source_server_address[0], source_server_address[1], body)
Example #18
0
    def __init__(self, ip, port):
        """
        The Stream object constructor.

        Code design suggestion:
            1. Make a separate Thread for your TCPServer and start immediately.



        :param ip: 15 characters
        :param port: 5 characters
        """
        def callback(address, queue, data):
            """
            The callback function will run when a new data received from server_buffer.

            :param address: Source address.
            :param queue: Response queue.
            :param data: The data received from the socket.
            :return:
            """
            queue.put(bytes('ACK', 'utf8'))
            self._server_in_buf.append(data)

        ip = Node.parse_ip(ip)
        port = Node.parse_port(port)
        self._server_in_buf = []
        self.parent_node_address = (None, None)
        self.nodes: List[Node] = []
        self.server = TCPServer(ip,
                                port,
                                callback,
                                maximum_connections=256,
                                receive_bytes=2048)
        threading.Thread(target=self.server.run).start()
        # todo: problem!. update:I think it's solved!
        pass
Example #19
0
    def add_message_to_out_buff(self, address, message, is_register_node=False):
        """
        In this function, we will add the message to the output buffer of the node that has the input address.
        Later we should use send_out_buf_messages to send these buffers into their sockets.

        :param is_register_node:
        :param address: Node address that we want to send the message
        :param message: Message we want to send

        Warnings:
            1. Check whether the node address is in our nodes or not.

        :return:
        """

        if is_register_node:
            if self.is_root:
                node = self.root_register_nodes[str(address)]
                node.add_message_to_out_buff(message)
            else:
                self.register_node.add_message_to_out_buff(message)
        else:
            node = self.nodes[str((Node.parse_ip(address[0]), Node.parse_port(address[1])))]
            node.add_message_to_out_buff(message)
Example #20
0
    def new_register_packet(kind, source_server_address, address=(None, None)):
        """
        :param kind: Type of Register packet
        :param source_server_address: Server address of the packet sender.
        :param address: If 'type' is 'request' we need an address; The format is like ('192.168.001.001', '05335').

        :type kind: str
        :type source_server_address: tuple
        :type address: tuple

        :return New Register packet.
        :rtype Packet

        """
        if kind == 'REQ':
            body = bytes('REQ', 'UTF-8') + bytes(
                Node.parse_ip(source_server_address[0]), 'UTF-8') + bytes(
                    str(Node.parse_port(source_server_address[1])), 'UTF-8')
            return PacketFactory.make_header(source_server_address, 1,
                                             len(body)) + body
        else:
            body = bytes('RES ACK', 'UTF-8')
            return PacketFactory.make_header(source_server_address, 1,
                                             len(body)) + body
Example #21
0
    def __init__(self,
                 server_ip,
                 server_port,
                 is_root=False,
                 root_address=None):
        """
        The Peer object constructor.

        Code design suggestions:
            1. Initialise a Stream object for our Peer.
            2. Initialise a PacketFactory object.
            3. Initialise our UserInterface for interaction with user commandline.
            4. Initialise a Thread for handling reunion daemon.

        Warnings:
            1. For root Peer, we need a NetworkGraph object.
            2. In root Peer, start reunion daemon as soon as possible.
            3. In client Peer, we need to connect to the root of the network, Don't forget to set this connection
               as a register_connection.


        :param server_ip: Server IP address for this Peer that should be pass to Stream.
        :param server_port: Server Port address for this Peer that should be pass to Stream.
        :param is_root: Specify that is this Peer root or not.
        :param root_address: Root IP/Port address if we are a client.

        :type server_ip: str
        :type server_port: int
        :type is_root: bool
        :type root_address: tuple
        """
        self.address = (Node.parse_ip(server_ip),
                        Node.parse_port(str(server_port)))
        self.root_address = None if root_address is None else Node.parse_address(
            root_address)
        self.stream = Stream(server_ip, server_port, root_address)
        self.packet_factory = PacketFactory()
        self.ui = UserInterface()
        self.ui.daemon = True
        self.is_root = is_root
        self.parent_address = None
        self.children = []

        self.network_graph = None
        self.registered_peers = None

        self.waiting_for_hello_back = False
        self.last_sent_hello_time = None
        self.reunion_daemon = threading.Thread(target=self.run_reunion_daemon)
        self.reunion_daemon.daemon = True

        if is_root:
            root_graph_node = GraphNode(self.address)
            root_graph_node.depth = 0
            self.network_graph = NetworkGraph(root_graph_node)
            self.registered_peers = dict()
            self.last_received_hello_times = dict()
            self.reunion_daemon.start()
        elif root_address is not None:
            self.stream.add_node(root_address, set_register_connection=True)

        self.start_user_interface()
        print('Peer initialized.')
Example #22
0
    def __init__(self,
                 server_ip,
                 server_port,
                 is_root=False,
                 root_address=None):
        """
        The Peer object constructor.

        Code design suggestions:
            1. Initialise a Stream object for our Peer.
            2. Initialise a PacketFactory object.
            3. Initialise our UserInterface for interaction with user commandline.
            4. Initialise a Thread for handling reunion daemon.

        Warnings:
            1. For root Peer, we need a NetworkGraph object.
            2. In root Peer, start reunion daemon as soon as possible.
            3. In client Peer, we need to connect to the root of the network, Don't forget to set this connection
               as a register_connection.


        :param server_ip: Server IP address for this Peer that should be pass to Stream.
        :param server_port: Server Port address for this Peer that should be pass to Stream.
        :param is_root: Specify that is this Peer root or not.
        :param root_address: Root IP/Port address if we are a client.

        :type server_ip: str
        :type server_port: int
        :type is_root: bool
        :type root_address: tuple
        """
        super().__init__()
        self.server_ip = Node.parse_ip(server_ip)
        self.server_port = Node.parse_port(str(server_port))
        self.server_address = (self.server_ip, self.server_port)
        self.stream = Stream(self.server_ip, self.server_port)
        self.UI = UserInterface()

        self.is_root = is_root
        self.left_child_address, self.right_child_address, self.parent_address = None, None, None

        if self.is_root:
            self.registered_peers_address = {}
            self.root_ip, self.root_port = self.server_ip, self.server_port
            self.root_node = GraphNode((self.root_ip, self.root_port))
            self.graph = NetworkGraph(self.root_node)

        else:
            self.root_ip = Node.parse_ip(root_address[0])
            self.root_port = Node.parse_ip(str(root_address[1]))

        self.root_address = (self.root_ip, self.root_port)

        self.running = True
        self.registered = False
        self.advertised = False
        self.joined = False
        self.reunion_on_fly = False
        self.reunion_timer = 0
        self.counter = 0
        self.timer_interval = 0.2
        self.UI.start()
        self.start()