def on_response_received(self, transaction):
        # Update the id of the remote node.
        transaction.response_node.id_20 = transaction.response["r"]["id"]

        # Add the node that reponded to us. We most likely already have this one.
        self._server.remote_nodes.add(transaction.response_node)

        # A find_node or get_peers response may carry extra nodes.
        if transaction.query["q"] == "find_node" or transaction.query["q"] == "get_peers":
            nodes = transaction.response["r"].get("nodes", "")

            for i in xrange(0, len(nodes), 26):
                id_26 = nodes[i : i + 26]
                if not self._server.remote_nodes.get_node(id_26):
                    self._server.remote_nodes.add(Node.from_id_26(id_26))
    def _receiver(self):
        """
        Run in a different thread, and have as only goal to receive messages,
        parse them, and put them into a thread safe queue for further handling
        """
        while True:
            try:
                # Receive message
                raw_message, connect_info = self._sock.recvfrom(4096)
                message = bdecode(raw_message)
#                print "Received f " + str(connect_info) + ":\t" + str(message)

                # This is a query from another peer.
                if message['y'] == 'q':
                    # Retrieve or create source node.
                    id_26 = message['a']['id'] + socket.inet_aton(connect_info[0]) + struct.pack(r'!H', connect_info[1])
                    source_node = self.remote_nodes.get_node(id_26) or Node.from_id_26(id_26)

                    transaction = Transaction(query=message, query_node=source_node, response_node=self.node) # create transaction
                    self._running_transactions[transaction.id] = transaction # Add it to running transactions

                    for handler in self.on_query_received:
                        handler(transaction)  # Notify listeners

                elif message['y'] == 'e':
                    raise Exception

                # This is a response to a transaction we started.
                elif message['y'] == 'r':
                    transaction = self._running_transactions.pop(message["t"]) # pop transaction
                    transaction.response = message

                    for handler in self.on_response_received:
                        handler(transaction)  # Notify listeners

                else:
                    raise Exception

            except socket.timeout:
                pass
            except BTFailure:
                pass
            except:
                print traceback.format_exc()