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)
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
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()
def get_server_address(self): """ :return: Our TCPServer address :rtype: tuple """ return Node.parse_ip(self._server.ip), Node.parse_port( self._server.port)
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
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
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
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
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
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
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
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
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
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
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)
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()
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)
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
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)
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
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.')
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()