def download_block(self, filename, id, ip, port): query = ZapTorrentProtocolResponse(response_type='download?', filename=filename, id=id, name=ZapConfig.name, ip=ZapConfig.ip, port=ZapConfig.tcp_port) msg = query.as_response() sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((ip, int(port))) self.send_to_socket(sock, msg) resp = sock.recv(54000) zap_debug_print("download_blocks got %s back" % resp) #TODO: what if we don't receive the # entire first chunk, or we get an error? if len(resp) == 0: raise RuntimeError("socket closed remotely!") parser = ZapTorrentProtocolParser(resp) parser.parse() if parser.message_type == 'download': #make sure we have the whole block while len(parser.fields['data']) < int(parser.fields['bytes']): parser.fields['data'] += sock.recv(54000) sock.close() return parser.fields['data'] else: zap_debug_print("Error downloading a block: got ", resp) sock.close() return None
def run(self): SIZE = 65000 while True: #TODO: what if not all the data comes at once? data, address = self.sock.recvfrom(SIZE) if address[0] == self.ip and address[1] == self.ignore_port: continue query = ZapTorrentProtocolParser(data) zap_debug_print("in zap_broadcast and got some data! ", data) zap_debug_print("address is", address) zap_debug_print("my ignoring stuff is", self.ip, self.ignore_port) query.parse() if query.message_type == 'error': self.sock.sendto(query.response, address) elif query.message_type == 'files?': #BUILD LIST OF FILES AND SEND BACK response = ZapTorrentProtocolResponse(response_type='files', name=ZapConfig.name, ip=self.ip, port=ZapConfig.tcp_port) for filename in self.local_files.get_files(): f = self.local_files.get_files()[filename][0] zap_debug_print("Adding a local file, and it is", f) response.add(f) zap_debug_print("response is ", response.as_response()) self.sock.sendto(response.as_response(), address)
def run(self): #TODO: what if we don't receive it all at once? msg = self.sock.recv(54000) zap_debug_print("Got a message on the ZAPTCPResponseThread and it is", msg) response = "" query = ZapTorrentProtocolParser(msg) query.parse() if query.message_type == 'error': response = query.response elif query.message_type == 'inventory?': #Look for the file in local_files f = self.local_files.get(query.fields['filename']) if f is None: response = "ZT 1.0 error No file named %s" % query.fields['filename'] else: f = f[0] r = ZapTorrentProtocolResponse(response_type="inventory", filename=f.filename, blocks=f.number_of_blocks) r.stuff_to_add = f.get_blocks(status='present') zap_debug_print("got back some blocks and they looks like this:", r.stuff_to_add) response = r.as_response() elif query.message_type == 'download?': #make sure we have the file f = self.local_files.get(query.fields['filename']) if f is None: response = "ZT 1.0 error No file named %s" % query.fields['filename'] else: f = f[0] if f.block_is_present(int(query.fields['id'])): r = ZapTorrentProtocolResponse(response_type="download", filename=f.filename, id=query.fields['id'], bytes=f.get_block(int(query.fields['id'])).get_bytes()) response = r.as_response() log_string = "upload %s %s %s %s %s %s" % (f.filename, ZapConfig.name, query.fields['ip'], query.fields['port'], query.fields['id'], len(f.get_block(int(query.fields['id'])).get_bytes())) zap_log(log_string) else: response = "ZT 1.0 error No block for %s at %s\n" % (f.filename, query.fields['id']) else: response = "ZT 1.0 error unknown TCP query type.\n" sent_length = 0 zap_debug_print("sending %s as response" % response) while sent_length < len(response): message_remaining = response[sent_length:] length = self.sock.send(message_remaining) sent_length += length #TODO: do I close it on my end? self.sock.close()
def get_available_blocks(self, ip, port, filename): """Return a list of blocks that the peer at ip, port has for the given filename.""" sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) query = ZapTorrentProtocolResponse(response_type='inventory?', filename=filename) msg = query.as_response() sock.connect((ip, int(port))) self.send_to_socket(sock, msg) results = sock.recv(54000) if len(results) == 0: raise RuntimeError("socket closed remotely") parser = ZapTorrentProtocolParser(results) parser.parse() sock.close() return [block['id'] for block in parser.get_blocks()]