def receive_file(self, filename: str, rng: Tuple[int, int], owner: tuple): # telling the nodes we NEED a file, therefore idx=-1 and data=None. msg = FileCommunication(self.name, owner[0], filename, rng) temp_s = create_socket(give_port()) self.send_datagram(temp_s, msg, owner[1]) print(f"Node {self.name} has sent the start-of-transfer message to " f"{owner[0]}.") while True: data, addr = temp_s.recvfrom(BUFFER_SIZE) dg: UDPDatagram = crypto_unit.decrypt(data) msg = Message.decode(dg.data) # msg now contains the actual bytes of the data for that file. # TODO some validation if msg["filename"] != filename: print(f"Wanted {filename} but received {msg['range']} range " f"of {msg['filename']}") return if msg["idx"] == -1: print(f"Node {self.name} received the end-of-transfer message " f"from {owner[0]}.") free_socket(temp_s) return self.received_files[filename].append(msg)
def handle_node(self, data, addr): dg = crypto_unit.decrypt(data) message = Message.decode(dg.data) message_mode = message['mode'] if message_mode == modes.HAVE: self.add_uploader(message, addr) elif message_mode == modes.NEED: self.search_file(message, addr) elif message_mode == modes.EXIT: self.exit_uploader(message, addr)
def search(self, filename: str) -> dict: message = NodeToTracker(self.name, modes.NEED, filename) temp_s = create_socket(give_port()) self.send_datagram(temp_s, message, TRACKER_ADDR) while True: data, addr = temp_s.recvfrom(BUFFER_SIZE) dg: UDPDatagram = crypto_unit.decrypt(data) if dg.src_port != TRACKER_ADDR[1]: raise ValueError(f"Someone other than the tracker with " f"port:{dg.src_port} sent {self.name} " f"the search datagram.") return Message.decode(dg.data)
def start_listening(self): while True: data, addr = self.rec_s.recvfrom(BUFFER_SIZE) dg: UDPDatagram = crypto_unit.decrypt(data) msg = Message.decode(dg.data) if "size" in msg.keys() and msg["size"] == -1: # meaning someone needs the file size self.tell_file_size(dg, msg) elif "range" in msg.keys() and msg["data"] is None: print(f"Node {self.name} received the start-of-transfer " f"message from Node {msg['src_name']}.") self.send_file(msg["filename"], msg["range"], msg["src_name"], dg.src_port)
def ask_file_size(self, filename: str, owner: tuple) -> int: # size == -1 means asking the size message = SizeInformation(self.name, owner[0], filename) temp_s = create_socket(give_port()) self.send_datagram(temp_s, message, owner[1]) while True: data, addr = temp_s.recvfrom(BUFFER_SIZE) dg: UDPDatagram = crypto_unit.decrypt(data) # TODO some validation free_socket(temp_s) return Message.decode(dg.data)["size"]