コード例 #1
0
ファイル: peer.py プロジェクト: darius/py-bittorrent
    def handshake(self, info_hash, peer_id):
        self.logger.debug('info_hash was', info_hash)
        # assert info_hash in self.client.torrents.keys()
        self.logger.debug('Received handshake resp from peer:', peer_id)
        # Replace old key in dictionary
        temp_peer_id = self.peer_id
        self.peer_id = peer_id
        self.client.peers[self.peer_id] = self.client.peers[temp_peer_id]
        del self.client.peers[temp_peer_id]
        """
        try:
            self.client.torrents[info_hash]
        except KeyError, e:
            self.logger.warning(
                    'Closing conn; client not serving torrent {}.'.format(info_hash))
            self.conn.close()
        """
        self.conn.enqueue_msg(WireMessage.construct_msg(2))  # Interested

        pieces_received = [x[0].received for x in self.client.torrent.pieces]
        if len(filter(lambda x: x, pieces_received)) > 0:
            assert len(pieces_received) == self.client.torrent.num_pieces
            bitfield = Bitfield(pieces_received).byte_array
            self.conn.enqueue_msg(WireMessage.construct_msg(
                5, bitfield))  # Bitfield
コード例 #2
0
ファイル: request.py プロジェクト: henglish3/BitTorrentClient
	def message_handle(cls, buf):
		message = WireMessage.decode(buf)
		if cls.debug:print 'Decoded message: ' + str(message) #\n\t
		
		if message[0][0] == 'port':
			cls.s.send(WireMessage.construct_msg(2))
			return True
		
		if message[0][0] == 'choke':
			still_choked = True
			while still_choked:
				msg = cls.s.recv(5)
				if struct.unpack('!I', msg[5][0]) == 1:
					still_choked = False
			return True
		
		if message[0][0] == 'unchoke':
			print '\'Unchoke\' received. Requesting blocks!\n'
			cls.s.send(WireMessage.construct_msg(6, 0, 0, 16384))
			cls.i = 0
			return True
		
		if message[0][0] == 'piece':
			if cls.debug:
				print 'Block received!!! block size is: ' + str(len(buf))
				print 'A piece should be of size: ' + str(cls.length)
			actual_block = buf[13:]
			#I am working with a 16384 block size torrent, this won't work otherwise
			#I would need to set up another check to make sure cls.length was reached
			cls.i = cls.i + 1
			print 'Received ' + str(cls.i) + ' of ' + str(cls.end) + ' pieces'
			#verify
			piece_hash = sha1(actual_block).digest()
			if (piece_hash != cls.pieces.read(20)):
				print 'Corrupted'
			else:
				print 'Verified!'
				cls.file.write(actual_block)
				#out now, or at end
			if cls.i < cls.end - 1:
				cls.s.send(WireMessage.construct_msg(6, cls.i, 0, 16384))
			else:
				if cls.i == cls.end - 1:
					cls.s.send(WireMessage.construct_msg(6, cls.i, 0, cls.last))
				else: 
					cls.s.close()
					cls.file.close()
					print 'Exiting'
					return False
			return True
		
		if message[0][0] == 'keep_alive':
			cls.s.send('\x00')
			return True
		return True
コード例 #3
0
ファイル: conn.py プロジェクト: tcjinr20/bitload
 def recv_msg(self, msg):
     msg_type, msg_contents = WireMessage.decode(msg)
     if msg_type == 'handshake':
         new_conn, addr = self.socket.accept()
         func = getattr(self.parent, msg_type)
         assert callable(func)
         func(new_conn, addr, msg_contents)
         return True
     raise Exception('Non-handshake message received.')
コード例 #4
0
ファイル: peer.py プロジェクト: darius/py-bittorrent
    def request_blocks(self, pieces, max_requests=1):
        if self.outstanding_requests > max_requests:
            return False
        for piece, peer_id in pieces:
            blocks = piece.suggest_blocks(max_requests)
            self.outstanding_requests += len(blocks)
            for block in blocks:
                self.logger.debug(
                    '% Requesting pi {}, offset {} and block length {} %'.
                    format(piece.index, block.begin, block.length))

                msg = WireMessage.construct_msg(6, piece.index, block.begin,
                                                block.length)
                self.conn.enqueue_msg(msg)
コード例 #5
0
ファイル: peer.py プロジェクト: darius/py-bittorrent
 def set_choking(self, am_choking):
     """Change client's choking status of peer based upon
         value of am_choking argument.
        Communicate new choking value to remote peer.
     """
     try:
         assert am_choking != self.choking  # Detect misuse
     except AssertionError:
         raise Exception('Error: No change in am_choking')
     self.am_choking = am_choking
     msg_id = None
     if self.am_choking:
         msg_id = 0
     else:
         msg_id = 1
     msg = WireMessage.construct_msg(msg_id)
     self.conn.enqueue_msg(msg)
コード例 #6
0
ファイル: peer.py プロジェクト: darius/py-bittorrent
 def set_interested(self, am_interested):
     """Change client's interest in peer based upon
         value of am_interested argument.
        Communicate new interest to remote peer.
     """
     try:
         assert am_interested != self.interested  # Detect misuse
     except AssertionError:
         raise Exception('Error: No change in am_interested')
     self.am_interested = am_interested
     msg_id = None
     if self.am_interested:
         msg_id = 2
     else:
         msg_id = 3
     msg = WireMessage.construct_msg(msg_id)
     self.conn.enqueue_msg(msg)
コード例 #7
0
ファイル: peer.py プロジェクト: darius/py-bittorrent
 def send_cancel(self, index, begin, length):
     msg = WireMessage.construct_msg(8, index, begin, length)
     self.conn.enqueue_msg(msg)
コード例 #8
0
ファイル: peer.py プロジェクト: darius/py-bittorrent
 def send_have(self, index):
     """Tell all peers that client has all blocks in piece[index].
     """
     msg = WireMessage.construct_msg(4, index)
     self.conn.enqueue_msg(msg)  # TODO: all peers
コード例 #9
0
ファイル: peer.py プロジェクト: darius/py-bittorrent
 def send_keep_alive(self):
     msg = WireMessage.construct_msg(-1)
     self.conn.enqueue_msg(msg)
コード例 #10
0
ファイル: peer.py プロジェクト: darius/py-bittorrent
 def request(self, index, begin, length):
     self.logger.debug('Got request')
     block_data = self.torrent.get_block(index, begin, length)
     msg = WireMessage.construct_msg(7, index, begin, block_data)
     self.conn.enqueue_msg(msg)
コード例 #11
0
        """
        buf = ""
        while True:
            try:
                msg = self.socket.recv(4096)
            except Exception, e:
                self.parent.mark_bad()
                self.logger.warning('recv() on {}:{}: {}'.format(
                    self.ip, self.port, e))
                #self.close()
                break
            else:
                if len(msg) == 0: break
                buf += msg
        if len(buf) == 0: return False
        messages = WireMessage.decode_all(buf)
        for msg in messages:
            func = getattr(self.parent, msg[0])
            assert callable(func)
            try:
                if msg[1]:
                    func(*msg[1])
                else:
                    func()
            except AttributeError, e:
                # Todo - make sure AttributeError actually relates to func()
                self.logger.error('Error: Invalid msg type {}'.format(msg[0]))
                raise Exception(e)

    def enqueue_msg(self, msg):
        self._outbound.append(msg)