def test_constructor(self): # TODO Test the constructor with additional malformed .torrent # files and look for the appropriate exceptions with pytest.raises(IOError): Metainfo("") with pytest.raises(ValueError): Metainfo("test_metainfo.py")
def __init__(self, ip_addr, port, filename): atexit.register(self.exit_handler) #list of peers (and connection info) that this client is connected to self.connection_list = list() self.listen_list = list() self.metainfo = Metainfo(filename) self.filename = filename self.ip_addr = ip_addr self.port = port self.peer_id = os.urandom(20) self.info_hash = self.metainfo.info_hash self.uploaded = 0 self.downloaded = 0 #if client has file, set left to 0 and bitfield to full self.tracker_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.tracker_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.tracker_socket.connect((socket.gethostbyname('localhost'), 6969)) self.bitfield = BitArray(self.metainfo.num_pieces) if (self.check_for_file()): self.bitfield.set(True) self.left = 0 else: self.bitfield.set(False) self.left = self.metainfo.file_length self.send_GET_request(0) self.listening_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.listening_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.listening_socket.bind( (socket.gethostbyname(self.ip_addr), self.port)) self.listening_socket.listen(5) # while True: # (opentracker_socket, opentracker_addr) = self.socket.accept() # response = socket.recv(4096) # print(response) tracker_response = self.tracker_socket.recv(1024) print("Response: ", tracker_response) status = re.split(" ", str(tracker_response)[2:-1]) if (status[1] != "200"): print("ERROR") else: print("parsing tracker response...") self.response = tracker_response self.handle_tracker_response() listening_thread = threading.Thread(target=self.listen_for_handshake) listening_thread.daemon = True listening_thread.start()
def setup_class(self): self.singlefile = Metainfo("ubuntu.torrent") self.multifile = Metainfo("multi.torrent")
def __init__(self, client, filename, port, peer_id): self._client = client self._filename = filename self._port = port self._peer_id = peer_id # _peers is a list of peers that the TorrentMgr is trying # to communicate with self._peers = [] # _bitfields is a dictionary mapping peers to a bitfield of the pieces # each has self._bitfields = {} try: self._metainfo = Metainfo(filename) except (IOError, ValueError) as err: if isinstance(err, IOError): message = err.strerror + ' (' + filename + ')' else: message = err.message + ' (' + filename + ')' logger.error(message) raise TorrentMgrError(message) # _have is the bitfield for this torrent. It is initialized to reflect # which pieces are already available on disk. self._filemgr = FileMgr(self._metainfo) self._have = self._filemgr.have() try: self._tracker_proxy = TrackerProxy(self._metainfo, self._port, self._peer_id) except TrackerError as err: logger.critical("Could not connect to tracker at {}".format( self._metainfo.announce)) logger.debug(" TrackerError: {}".format(err.message)) raise TorrentMgrError(err.message) # _needed is a dictionary of pieces which are still needed. # The value for each piece is a tuple of the number of peers which # have the piece and a list of those peers. self._needed = { piece: (0, []) for piece in list(self._have.findall('0b0')) } # _interested is a dictionary of peers to whom interest has been # expressed. The value for each peer is a tuple of the piece that # has been reserved for the peer, the number of bytes of the piece that # have already been received, the sha1 hash of the bytes received so # far and the value of the tick at the time interest was expressed. self._interested = {} # _requesting is a dictionary of peers to whom a block request has been # made. The value for each peer is a tuple of the piece that is being # requested, the number of bytes that have already been received, the # shal2 hash of the bytes received so far, the value of the tick at # the time the request was made and the number of retries that have # been attempted self._requesting = {} # _partial is a list which tracks pieces that were interrupted while # being downloaded. Each entry is a tuple containing the index of the # piece, the number of bytes received so far and the sha1 hash of those # bytes. self._partial = [] self._reactor = Reactor() self._reactor.schedule_timer(_TIMER_INTERVAL, self.timer_event) self._tick = 1 print "Starting to serve torrent {}".format(filename) self._connect_to_peers(20)
from torrent import Torrent from metainfo import Metainfo if __name__ == '__main__': torrent_name = './resource/Haywyre-Panorama_Form.torrent' torrent_name = './resource/Berklee Online.torrent' torrent_name = './resource/BLUMBROS X MAKJ - LS6.torrent' #metainfo = Metainfo(torrent_name) #print(metainfo.info) torrent = Torrent(Metainfo(torrent_name)) torrent.start_torrent()
def initialize(self): """ initialize() returns a deferred which fires when initialization of the TorrentMgr is complete or an error has occurred. """ if self._state != self._States.Uninitialized: error = "TorrentMgr can't be reinitialized" logger.debug(error) d = Deferred() d.errback(TorrentMgrError(error)) return d try: self._metainfo = Metainfo(self._filename) except ValueError as err: logger.error(err) d = Deferred() d.errback(TorrentMgrError(err.message)) return d except IOError as err: logger.error(err) d = Deferred() d.errback(TorrentMgrError(err.strerror)) return d # _peers is a list of peers that the TorrentMgr is trying # to communicate with self._peers = [] # _bitfields is a dictionary mapping peers to a bitfield of the pieces # each has self._bitfields = {} # _have is the bitfield for this torrent. It is initialized to reflect # which pieces are already available on disk. self._filemgr = FileMgr(self._metainfo) self._have = self._filemgr.have() # _needed is a dictionary of pieces which are still needed. # The value for each piece is a tuple of the number of peers which # have the piece and a list of those peers. self._needed = { piece: (0, []) for piece in list(self._have.findall('0b0')) } # _interested is a dictionary of peers to whom interest has been # expressed. The value for each peer is a tuple of the piece that # has been reserved for the peer, the number of bytes of the piece that # have already been received, the sha1 hash of the bytes received so # far and the value of the tick at the time interest was expressed. self._interested = {} # _requesting is a dictionary of peers to whom a block request has been # made. The value for each peer is a tuple of the piece that is being # requested, the number of bytes that have already been received, the # shal2 hash of the bytes received so far, the value of the tick at # the time the request was made and the number of retries that have # been attempted self._requesting = {} # _partial is a list which tracks pieces that were interrupted while # being downloaded. Each entry is a tuple containing the index of the # piece, the number of bytes received so far and the sha1 hash of those # bytes. self._partial = [] self._tracker_proxy = TrackerProxy(self._metainfo, self._port, self._peer_id) def success(result): self._state = self._States.Initialized def failure(failure): logger.critical("Could not connect to tracker at {}".format( self._metainfo.announce)) message = failure.value.message logger.debug(" Tracker Error: {}".format(message)) raise TorrentMgrError(message) return self._tracker_proxy.start().addCallbacks(success, failure)
def __init__(self, ip_addr, port, filename): #list of peers (and connection info) that this client is connected to self.connection_list = list() self.listen_list = list() self.metainfo = Metainfo(filename) self.filename = filename self.ip_addr = ip_addr self.port = port self.peer_id = os.urandom(20) self.info_hash = self.metainfo.info_hash self.uploaded = 0 self.downloaded = 0 #if client has file, set left to 0 and bitfield to full self.tracker_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.tracker_socket.connect((socket.gethostbyname('localhost'), 6969)) self.bitfield = BitArray(self.metainfo.num_pieces) if(self.check_for_file()): self.bitfield.set(True) self.left = 0 else: self.bitfield.set(False) self.left = self.metainfo.file_length self.send_GET_request(0) self.listening_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.listening_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.listening_socket.bind((socket.gethostbyname(self.ip_addr), self.port)) self.listening_socket.listen(5) # while True: # (opentracker_socket, opentracker_addr) = self.socket.accept() # response = socket.recv(4096) # print(response) tracker_response = self.tracker_socket.recv(2048) print(tracker_response) status = re.split(" ", tracker_response.decode('utf-8')) if(status[1] != "200"): print("ERROR") else: print("parsing tracker response...") self.response = tracker_response self.handle_tracker_response() #listen for handshakes i = 0 while True: i = i + 1 peer_connection, address = self.listening_socket.accept() print(i) buf = peer_connection.recv(1024) print("maybe receive stuff") #print(len(buf)) #if message is handshake if buf[0]==18 and buf[1:19] == b'URTorrent protocol' and buf[19:27] == b'\x00\x00\x00\x00\x00\x00\x00\x00' and buf[27:47] == self.info_hash.digest(): #if len(buf) > 0 and "URTorrent" in str(buf): #ip = connection_socket.getsockname()[0] #port = connection_socket.getsockname()[1] #connection_socket.close() print("Received valid handshake", buf) peer_connection.send(self.generate_handshake_msg()) #split off thread to listen for piece requests on this socket peer_connection.settimeout(120) threading.Thread(target = self.listen_to_peer, args = (peer_connection, address)).start()