Ошибка сокета 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, но при передаче по сети данные должны быть байтовыми строками. Итак... пара предложений:
- Предложите использовать
c.sendall()
вместо c.send()
чтобы предотвратить возможные проблемы, когда вы, возможно, не отправили все сообщения одним вызовом (см. Документацию). - Для литералов добавьте строку
'b'
для байтов: c.sendall(b'Thank you for connecting')
- Для переменных вам необходимо закодировать строки 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
вместо этого делает это байтами.