Если вы просто отправляете литералы, вы можете просто использовать литерал bytes
вместо литерала str
, поставив перед ним префикс b
.Вместо этого:
sock.send('Hello')
… просто сделайте это:
sock.send(b'Hello')
Если вы отправляете строковые переменные, вам нужно будет encode
их для отправки, ивероятно decode
их при получении.Вместо этого:
sock.send(msg)
resp = sock.recv(4096)
… do:
sock.send(msg.encode('ascii')
resp = sock.recv(4096).decode('ascii')
Если вы хотите отправлять не-ASCII строки, вам нужно выбрать кодировку.Если у вас нет веских причин поступить иначе, используйте UTF-8.
Еще одна вещь, которую нужно иметь в виду: сокеты TCP - это просто потоки байтов, а не сообщений, и их можно произвольно разделитьв пакеты.Когда вы можете recv(1024)
, вы можете получить только часть того, что отправила другая сторона с send
.Это, вероятно, очевидно, если вы отправляете строки длиннее 1024 байта, но даже для более коротких строк это может произойти.Или, если вы не строго чередуете отправку и получение, вы можете объединить несколько отправок в один прием.И если вы отправите hello
, а затем world
и получите их как helloworld
, у вас нет возможности узнать, что произошло, или как разделить их на части.
И, что еще хуже, вероятно, не произойдет , когда вы тестируете на локальном хосте на простаивающей машине, так что во время разработки все будет хорошо выглядеть, но затем, когда вы его где-то развернете, произойдет таинственный сбой.
Итак,вам нужен протокол, который описывает, где заканчивается одно сообщение и начинается другое.У меня пост в блоге , который объясняет некоторые опции и показывает, как их реализовать.
Но если вы просто отправляете понятные человеку строки в качестве сообщений, и эти строки никогда не будут содержать переводы строк.Простейший протокол - это просто строка для каждого сообщения, точно так же, как вы пишете текстовый файл.И посмотрите на socket.makefile
: он дает вам что-то, что действует как файл, обрабатывает одну строку для каждого протокола сообщений, а также автоматически обрабатывает части encode
и decode
.Итак, вместо этого:
sock.send(msg.encode('utf-8'))
resp = sock.recv(1024).decode('utf-8')
… вы просто используете makefile
для получения читаемых и записываемых файловых объектов, затем выполните:
wf.write(msg + '\n')
resp = next(rf)
… и тогда вы ненадо беспокоиться о том, как буферизовать получаемые данные и разбивать их на сообщения.