Ошибка сокета Python TypeError: необходим байтоподобный объект, а не 'str' с функцией отправки

Я пытаюсь создать программу, которая откроет порт на локальном компьютере и позволит другим подключаться к нему через netcat. Мой текущий код.

s = socket.socket()
host = '127.0.0.1'
port = 12345
s.bind((host, port))

s.listen(5)
while True:
    c, addr = s.accept()
    print('Got connection from', addr)
    c.send('Thank you for connecting')
    c.close()

Я новичок в Python и сокетах. Но когда я запустил этот код, он позволит мне отправить netcat-соединение с помощью команды:

nc 127.0.0.1 12345

Но потом на моем Python script я получаю ошибку для c.send:

TypeError: a bytes-like object is required, not 'str'

Я просто пытаюсь открыть порт, разрешить netcat подключаться и иметь полную оболочку на этой машине.

Ответ 1

Причиной этой ошибки является то, что в Python 3 строки имеют Unicode, но при передаче по сети данные должны быть байтовыми строками. Итак... пара предложений:

  1. Предложите использовать c.sendall() вместо c.send() чтобы предотвратить возможные проблемы, когда вы, возможно, не отправили все сообщения одним вызовом (см. Документацию).
  2. Для литералов добавьте строку 'b' для байтов: c.sendall(b'Thank you for connecting')
  3. Для переменных вам необходимо закодировать строки Unicode в строки байтов (см. Ниже)

Лучшее решение (должно работать с 2.x и 3.x):

output = 'Thank you for connecting'
c.sendall(output.encode('utf-8'))

Эпилог/история: это не проблема в Python 2, потому что строки уже являются байтовыми строками - ваш OP-код будет отлично работать в этой среде. Строки Unicode были добавлены в Python в выпусках 1.6 и 2.0, но оставались на заднем плане до 3.0, когда они стали типом строки по умолчанию. Также посмотрите этот похожий вопрос, а также этот.

Ответ 2

Вы можете декодировать его на str с помощью receive.decode('utf_8').

Ответ 3

Вы можете изменить строку отправки на это:

c.send(b'Thank you for connecting')

b вместо этого делает это байтами.