В качестве контекста для моего вопроса я впервые участвую в Python. До этого я работал в основном с Java, и сейчас я лучше всего разбираюсь в соглашениях и практиках Java.Программирование сокетов Python 3: использование sendall vs. sendto
фон
Уступка для программирования сокетов спрашивает, что мы посылаем строки между сервером и клиентом на локальном компьютере. Нам предоставляется образец (Python 2), который создает сервер и клиент. Вне контекста задания, я хотел создать версию этого кода, который также работает в Python 3, но у меня были проблемы с получением клиента работать так же в Python 3.
Изменение сервера и клиента
Первоначально сервер требовал незначительных изменений, и я смог заставить его работать. Мой код сервера выглядит следующим образом:
#!/usr/bin/python3
import socket
HOST=''
PORT=5870
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((HOST, PORT))
sock.listen(1)
conn, addr = sock.accept()
print('Connected by ', addr)
conn.sendto("Welcome to the server!", (HOST, PORT))
while True:
data = conn.recv(1024)
if not data: break
conn.sendall(data)
conn.close()
Я не в состоянии преобразовать стороне клиента в код, который работает и функционирует в Python 3. Я попытался углубиться в проблему, но и другие интернет-ресурсы не помогают мне (или, по крайней мере, на моем уровне опыта). Мой код сервера выглядит следующим образом.
#!/usr/bin/python3
import socket
HOST='127.0.0.1'
PORT=5870
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
data = sock.recv(1024)
print('Server sent', data)
sock.sendto("Hello world".encode(), (HOST, PORT))
data = sock.recv(1024)
print("Server sent", data)
sock.sendto("This is the second message".encode(), (HOST, PORT))
data = sock.recv(1024)
print('Server sent ', data)
sock.close()
Реальная проблема
Первоначально этот код сервера и клиента используется sendall()
вместо sendto()
, но я изменил его после получения TypeError
в клиенте и чтение this question. Я все еще не совсем уверен, почему это работает или почему я должен это делать (хотя я был бы признателен за объяснение).
Теперь, когда я запускаю клиентский код, я получаю тот же TypeError
на сервере, даже когда я использую sendto()
, но я не уверен, как решить эту проблему на Python 3. Стоп-трасса, которую я получаю для сервера следующим образом (я сломанную трубку на клиенте):
$ python3 mail_server.py
Connected by ('127.0.0.1', 41866)
Traceback (most recent call last):
File "mail_server.py", line 14, in <module>
conn.sendto("Welcome to the server!", (HOST, PORT))
TypeError: a bytes-like object is required, not 'str'
Что я делаю неправильно и как я смог получить эту работу в Python 3? Фоновый контекст, почему это было бы особенно полезно, поскольку, по моему мнению, часть моей проблемы заключается в том, что я не вижу, почему это изменение необходимо для начала. Благодаря!
'SendTo()' для датаграмм сокетов, а не поток сокеты. С потоковым сокером вам не нужно указывать, куда отправлять, потому что поток уже подключен к определенной конечной точке. – Barmar
@ Бармар я вижу. Итак, как я смогу создать сокет потока для приложения этой программы? Есть ли что-то другое, что я должен делать, или мне нужно внести изменения в использование 'sendall()', чтобы заставить его работать, как я бы хотел? – jflory7
'sock.accept()' возвращает сокет потока, вам не нужно ничего делать специальным. – Barmar