Как исправить: UnicodeDecodeError: код 'utf-8' c не может декодировать байт 0x81 в позиции 18: недопустимый начальный байт - PullRequest
0 голосов
/ 04 августа 2020

Я пытаюсь создать удаленную оболочку, используя сокеты. Некоторые команды работают как netstat или dir. Но когда я пытаюсь использовать ping, появляется это сообщение об ошибке:

  • UnicodeDecodeError: код 'utf-8' c не может декодировать байт 0x81 в позиции 18: недопустимый начальный байт

Эта проблема возникает только на стороне сервера, если я попытаюсь закодировать сообщение в utf-8. С обычной байтовой строкой работает нормально. Я также пытался сначала получить, а затем закодировать строку.

На стороне сервера:

    while True:
        cmd = input(">>>")

        if len(str.encode(cmd)) > 0:
            connection.send(str.encode(cmd))

            client_response = str(connection.recv(1024), encoding = "utf-8")

            print (client_response, end = "")

На стороне клиента:

    while True:
        data = sock.recv(1024).decode("utf-8")

        proc = subprocess.Popen(shlex.split(data),
                                shell = True,
                                stdin = subprocess.PIPE,
                                stdout = subprocess.PIPE,
                                stderr = subprocess.PIPE)

        output = proc.stdout.read()+proc.stderr.read()

        sock.send(output)

Может быть, кто-нибудь может дать мне совет .

1 Ответ

0 голосов
/ 04 августа 2020

Кстати, я думаю, что ваши определения клиента и сервера могут быть неправильными. Клиент должен быть тем, кто принимает вводимые пользователем данные и отправляет их на сервер для выполнения. Однако это не имеет отношения к вашему вопросу.

Однако я буду называть их стороной пользователя (где пользователь вводит команды) и стороной выполнения (где выполняется процесс), чтобы, надеюсь, избежать недоразумений.

Я вижу, что для вывода на стороне выполнения ссылки не выполняется кодирование, вы просто возвращаете стандартный вывод и ошибку как есть.

Я бы предложил распечатать это перед отправкой, чтобы вы можно увидеть, что он содержит, а также распечатать его до попытки преобразования на стороне пользователя:

# On exection side:
output = proc.stdout.read()+proc.stderr.read()
print('before send', output)

# On user side:
client_response = connection.recv(1024)
print('got response', client_response)
client_response = str(client_response, encoding = "utf-8")

Начальный байт 0x81 очень недействителен как UTF-8 начальный байт - либо крайний левый бит должен быть установлен в ноль, либо два крайних левых бита должны быть установлены в единицу. 0x81 является двоичным 1000 0001, поэтому не соответствует этому требованию.

...