def transfer(message, socket): _from, to, how_many, date = message[1:] if _from in transactions or to in transactions: socket.send(builder("retry")) transactions.append(_from) transactions.append(to) with open("logs/now", "a") as f: f.write("-%s:%s:%s:%s\n" % (_from, to, how_many, date)) with open("clients/%s" % _from, "r+") as f: money = int(f.read() or "0") f.seek(0) f.write(str(money - int(how_many))) f.truncate() with open("clients/%s" % to, "r+") as f: money = int(f.read() or "0") f.seek(0) f.write(str(money + int(how_many))) f.truncate() transactions.remove(_from) transactions.remove(to) socket.send(builder("success"))
def request(self, piece, start, length): self.socket.send(builder('interested')) while True: message = parser(self.socket.recv(400000)) if not message: continue if message[0] == 'unchoke': self.socket.send(builder('request', piece, start, length)) if message[0] == 'piece': self.write_block(message[1]) return
def parse_request(socket, torrent, piece_index, start, block_length): BLOCK_SIZE = 2 ** 14 blocks_per_piece = (torrent['info']['length'] / 10) / BLOCK_SIZE with open("examples/file.txt") as f: offset = piece_index * blocks_per_piece * BLOCK_SIZE f.seek(start * BLOCK_SIZE + offset) content = f.read(block_length) socket.send(builder('piece', piece_index, start, content))
def handshake(data, socket): pstrlen, pstr, reserved, info_hash, peer_id = struct.unpack("!i19sh40s20s", data) torrent = has_torrent(info_hash) if not torrent: socket.close() return # send handshake back socket.send(data) import time time.sleep(1) # send bitfield with pieces message = builder('bitfield', get_bitfield(torrent)) socket.send(message) return torrent
def handle(socket, address): torrent = None while True: data = socket.recv(2048) if not data: print "Client disconnected" break if len(data) == 85: torrent = handshake(data, socket) continue message = parser(data) if message[0] == 'interested': message = builder('unchoke') socket.send(message) if message[0] == 'request': parse_request(socket, torrent, *message[1])
def transfer_from(self, client, to, how_much, times=0): if times >= 3: return False with open("db/clients.txt") as f: clients = f.read() if "%s:" % client not in clients: raise ValueError("%s is not a client" % client) if "%s:" % to not in clients: raise ValueError("%s is not a client" % to) client = sha1(client).hexdigest() to = sha1(to).hexdigest() message = builder('transfer', client, to, int(how_much), int(time.time())) self.socket.send(message) response = parser(self.socket.recv(2048)) if response is not None and response[0] == 'retry': time.sleep(1) self.transfer_from(client, to, how_much, times + 1) elif response is not None and response[0] == 'success': return True