<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def receive(self, ikpdb):
 """Waits for a message from the debugger and returns it as a dict. """

        # with self._connection_lock:
        while self._network_loop:
            _logger.n_debug("Enter socket.recv(%s) with self._received_data = %s", 
                            self.SOCKET_BUFFER_SIZE, 
                            self._received_data)
            try:
                # We may land here with a full packet already in self.received_data
                # In that case we must not enter recv() 
                if self.SOCKET_BUFFER_SIZE:
                    data = self._connection.recv(self.SOCKET_BUFFER_SIZE)
                else:
                    data = b''
                _logger.n_debug("Socket.recv(%s) => %s", self.SOCKET_BUFFER_SIZE, data)

            except socket.timeout:
                _logger.n_debug("socket.timeout witk ikpdb.status=%s", ikpdb.status)
                if ikpdb.status == 'terminated':
                    _logger.n_debug("breaking IKPdbConnectionHandler.receive() "
                                    "network loop as ikpdb state is 'terminated'.")
                    return {    
                        'command': '_InternalQuit',
                        'args':{}
                    }
                continue

            except socket.error as socket_err:
                if ikpdb.status == 'terminated':
                    return {'command': '_InternalQuit', 
                            'args':{'socket_error_number': socket_err.errno,
                                    'socket_error_str': socket_err.strerror}}
                continue
            
            except Exception as exc:
                _logger.g_error("Unexecpected Error: '%s' in IKPdbConnectionHandler"
                                ".command_loop.", exc)
                _logger.g_error(traceback.format_exc())
                print("".join(traceback.format_stack()))
                return {    
                    'command': '_InternalQuit',
                    'args':{
                        "error": exc.__class__.__name__,
                        "message": exc.message
                    }
                }
    
            # received data is utf8 encoded
            self._received_data += data.decode('utf-8')
                
            # have we received a MAGIC_CODE
            try:
                magic_code_idx = self._received_data.index(self.MAGIC_CODE)
            except ValueError:
                continue
            
            # Have we received a 'length='
            try:
                length_idx = self._received_data.index(u'length=')
            except ValueError:
                continue
            
            # extract length content from received data
            json_length = int(self._received_data[length_idx + 7:magic_code_idx])
            message_length = magic_code_idx + len(self.MAGIC_CODE) + json_length
            if message_length <= len(self._received_data):
                full_message = self._received_data[:message_length]
                self._received_data = self._received_data[message_length:]
                if len(self._received_data) > 0:
                    self.SOCKET_BUFFER_SIZE = 0
                else:
                    self.SOCKET_BUFFER_SIZE = 4096
                break
            else:
                self.SOCKET_BUFFER_SIZE = message_length - len(self._received_data)

        self.log_received(full_message)
        obj = self.decode(full_message)
        return obj