Example #1
0
    def connect(self):
        handshake = self.torrent.get_handshake()

        self.sock = socket.socket()
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.sock.setblocking(True)

        try:
            print('peer info is ', self.peer_info)
            self.sock.connect(self.peer_info)
            self.sock.send(handshake)
        except OSError:
            raise Exception("Failed to connect")

        resp = self.sock.recv(2**15)

        print(resp)

        if not self.is_handshake_valid(handshake, resp):
            print("Failed to connect to {} -- invalid handshake".format(self.peer_info))
        else:
            print("{} connected successfully".format(self.peer_info))
            self.is_connected = True
            self.am_interested = True
            self.outbound_messages.append(
                MessageParser.encode_msg('interested')
            )

        self.recieved_data_buffer = resp[68:]
        self.process_read_buffer()
Example #2
0
    def connect(self):
        handshake = self.torrent.get_handshake()

        self.sock = socket.socket()
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.sock.setblocking(True)

        try:
            print('peer info is ', self.peer_info)
            self.sock.connect(self.peer_info)
            self.sock.send(handshake)
        except OSError:
            raise Exception("Failed to connect")

        resp = self.sock.recv(2**15)

        print(resp)

        if not self.is_handshake_valid(handshake, resp):
            print("Failed to connect to {} -- invalid handshake".format(
                self.peer_info))
        else:
            print("{} connected successfully".format(self.peer_info))
            self.is_connected = True
            self.am_interested = True
            self.outbound_messages.append(
                MessageParser.encode_msg('interested'))

        self.recieved_data_buffer = resp[68:]
        self.process_read_buffer()
Example #3
0
    def enqueue_piece_requests(self):
        while len(self.outbound_messages) < self.MAX_OUTBOX_REQUESTS:
            if self.am_interested and not self.is_choking:
                req = self.torrent.get_next_request(self.pieces)

                if not req: return

                index, begin, length = req
                payload = struct.pack('>III', index, begin, length)
                req_msg = MessageParser.encode_msg('request', payload)
                self.outbound_messages.append(req_msg)
            else:
                return
Example #4
0
    def enqueue_piece_requests(self):
        while len(self.outbound_messages) < self.MAX_OUTBOX_REQUESTS:
            if self.am_interested and not self.is_choking:
                req = self.torrent.get_next_request(self.pieces)

                if not req: return

                index, begin, length = req
                payload = struct.pack('>III', index, begin, length)
                req_msg = MessageParser.encode_msg('request', payload)
                self.outbound_messages.append(req_msg)
            else:
                return
Example #5
0
    def process_read_buffer(self):
        while self.recieved_data_buffer:

            msg_length = struct.unpack('>I', self.recieved_data_buffer[0:4])[0]
            packet_length = msg_length + 4

            # If the buffer doesn't contain the entirety of the packet then
            # break and wait until more data is read from socket
            if len(self.recieved_data_buffer) < packet_length:
                break

            message = MessageParser.parse(
                self.recieved_data_buffer[:packet_length],
                msg_length
            )

            self.recieved_data_buffer = self.recieved_data_buffer[packet_length:]
            if message.name != 'piece':
                print(message)
            else:
                print("We got a piece of our file!!!")
            # print('buffer is: ', self.recieved_data_buffer)

            # Msg ID 0
            if message.name == 'choke':
                self.is_choking = True

            # Msg ID 1
            if message.name == 'unchoke':
                self.is_choking = False

            # Msg ID 2
            if message.name == 'interested':
                # TODO: send unchoke message
                self.outbound_messages.append(
                    MessageParser.encode_msg('unchoke')
                )

            # Msg ID 3
            if message.name == 'not_interested':
                self.is_interested = False

            # Msg ID 4
            if message.name == 'have':
                have_piece = struct.unpack('>I', message.payload)[0]
                self.pieces[have_piece] = True

            # Msg ID 5
            if message.name == 'bitfield':
                self.pieces = BitArray(bytes=message.payload)
                self.outbound_messages.append(
                    MessageParser.encode_msg('interested')
                )

            # Msg ID 6
            if message.name == 'request':
                if not self.am_choking:
                    # Find piece from our downloaded torrent and send it back
                    pass

            # Msg ID 7
            if message.name == 'piece':
                self.inflight_requests -= 1
                index, begin = struct.unpack('>I I', message.payload[:8])
                print('Piece index: ', index)
                print(message.payload[:50])
Example #6
0
    def process_read_buffer(self):
        while self.recieved_data_buffer:

            msg_length = struct.unpack('>I', self.recieved_data_buffer[0:4])[0]
            packet_length = msg_length + 4

            # If the buffer doesn't contain the entirety of the packet then
            # break and wait until more data is read from socket
            if len(self.recieved_data_buffer) < packet_length:
                break

            message = MessageParser.parse(
                self.recieved_data_buffer[:packet_length], msg_length)

            self.recieved_data_buffer = self.recieved_data_buffer[
                packet_length:]
            if message.name != 'piece':
                print(message)
            else:
                print("We got a piece of our file!!!")
            # print('buffer is: ', self.recieved_data_buffer)

            # Msg ID 0
            if message.name == 'choke':
                self.is_choking = True

            # Msg ID 1
            if message.name == 'unchoke':
                self.is_choking = False

            # Msg ID 2
            if message.name == 'interested':
                # TODO: send unchoke message
                self.outbound_messages.append(
                    MessageParser.encode_msg('unchoke'))

            # Msg ID 3
            if message.name == 'not_interested':
                self.is_interested = False

            # Msg ID 4
            if message.name == 'have':
                have_piece = struct.unpack('>I', message.payload)[0]
                self.pieces[have_piece] = True

            # Msg ID 5
            if message.name == 'bitfield':
                self.pieces = BitArray(bytes=message.payload)
                self.outbound_messages.append(
                    MessageParser.encode_msg('interested'))

            # Msg ID 6
            if message.name == 'request':
                if not self.am_choking:
                    # Find piece from our downloaded torrent and send it back
                    pass

            # Msg ID 7
            if message.name == 'piece':
                self.inflight_requests -= 1
                index, begin = struct.unpack('>I I', message.payload[:8])
                print('Piece index: ', index)
                print(message.payload[:50])