def download_files(self): while True: if self.disconnect: break if not self.cur_info: continue else: filenames = [] for filename in self.cur_info["info"]: if filename not in self.completed_files: filenames.append(filename) if len(filenames) == 0: continue chosen_file = random.choice(filenames) potential_peers = [] for peer in self.cur_info["info"][chosen_file]["peers"]: if peer is not None: if chosen_file not in self.all_files: self.all_files[chosen_file] = { "cur_chunk": 0, } if self.all_files[chosen_file]["cur_chunk"] < peer["cur_chunk"]: potential_peers.append(peer) chosen_peer = random.choice(potential_peers) start_chunk = self.all_files[chosen_file]["cur_chunk"] end_chunk = min( start_chunk + MAX_SEND_CHUNKS, self.cur_info["info"][chosen_file]["info"]["numchunks"] ) download_socket = socket(AF_INET, SOCK_STREAM) try: download_socket.connect((chosen_peer["addr"], chosen_peer["upload_port"])) msg = { "filename": chosen_file, "start_chunk": start_chunk, "end_chunk": end_chunk } packet.send_msg(download_socket, json.dumps(msg).encode()) peer_msg = packet.recv_msg(download_socket) except: continue P2PFile.write_to_file(chosen_file, peer_msg) download_socket.close() self.all_files[chosen_file]["cur_chunk"] = end_chunk if end_chunk == self.cur_info["info"][chosen_file]["info"]["numchunks"]: self.completed_files.add(chosen_file) # send update to tracker self.update_tracker(chosen_file, end_chunk)
def connect_to_tracker(self): tracker_sock = socket(AF_INET, SOCK_STREAM) tracker_sock.connect((self.tracker_addr, self.tracker_port)) msg = { "type": "CONNECT", "file_info": self.my_orig_files, "upload_port": self.upload_sock_port, "listen_port": self.listen_sock_port } packet.send_msg(tracker_sock, json.dumps(msg).encode()) self.id = int(packet.recv_msg(tracker_sock).decode()) tracker_sock.close()
def update_peers(self): for i in range(0, MAX_PEERS): if self.all_info.peers[i]: update_peer_sock = socket(AF_INET, SOCK_STREAM) peer_info = self.all_info.peers[i] update_peer_sock.connect( (peer_info["addr"], peer_info["listen_port"])) msg = { "info": self.all_info.info, "peers": self.all_info.peers } packet.send_msg(update_peer_sock, json.dumps(msg).encode()) update_peer_sock.close()
def update_tracker(self, filename, cur_chunk): while True: try: tracker_sock = socket(AF_INET, SOCK_STREAM) tracker_sock.connect((self.tracker_addr, self.tracker_port)) msg = { "id": self.id, "type": "DOWNLOADED", "filename": filename, "cur_chunk": cur_chunk } packet.send_msg(tracker_sock, json.dumps(msg).encode()) tracker_sock.close() break except: continue
def upload_files(self): self.upload_sock.listen(1) while True: try: peer_sock, addr = self.upload_sock.accept() except: if self.disconnect: break continue peer_msg = json.loads(packet.recv_msg(peer_sock).decode()) msg = P2PFile.get_bytes_from_file_in_shared( peer_msg["filename"], peer_msg["start_chunk"], peer_msg["end_chunk"] ) packet.send_msg(peer_sock, msg) # peer_sock.send(msg) peer_sock.close()
def timeout(self): tracker_sock = socket(AF_INET, SOCK_STREAM) tracker_sock.connect((self.tracker_addr, self.tracker_port)) msg = { "type": "DISCONNECT", "id": self.id } packet.send_msg(tracker_sock, json.dumps(msg).encode()) all_files = P2PFile.get_all_info_in_shared() print("PEER {} SHUTDOWN: HAS {}".format( self.id, len(all_files) )) for fileinfo in all_files: print("{} {}".format( self.id, fileinfo["filename"] )) self.disconnect = True
def listen_to_peers(self): self.sock.listen(1) while True: peer_socket, addr = self.sock.accept() peer_addr = addr[0] peer_port = addr[1] peer_msg = json.loads(packet.recv_msg(peer_socket).decode()) if peer_msg["type"] == "CONNECT": packet.send_msg(peer_socket, str(self.cur_peer_num).encode()) files_info = [] for file_info in peer_msg["file_info"]: p2pfile = P2PFile.load_file_info(file_info) files_info.append(p2pfile) peer_file_info = PeerFileInfo(self.cur_peer_num, peer_addr, peer_msg["upload_port"], peer_msg["listen_port"], p2pfile, complete=True) self.all_info.add_peer_info(peer_file_info) self.output_peer_files(self.cur_peer_num, files_info) self.cur_peer_num += 1 elif peer_msg["type"] == "DISCONNECT": self.all_info.remove_peer_info(int(peer_msg["id"])) elif peer_msg["type"] == "DOWNLOADED": peer_id = peer_msg["id"] filename = peer_msg["filename"] cur_chunk = peer_msg["cur_chunk"] self.all_info.update_peer_info(peer_id, filename, cur_chunk) self.update_peers() peer_socket.close()