Python3套接字编程:使用sendall与sendto

Python3套接字编程:使用sendall与sendto,python,sockets,python-3.x,networking,Python,Sockets,Python 3.x,Networking,关于我的问题,我是一名计算机专业的学生,第一次开始学习Python。在此之前,我主要使用Java,现在我最熟悉Java约定和实践 背景 套接字编程的分配要求我们在机器上本地的服务器和客户端之间发送字符串。我们提供了实例化服务器和客户机的示例(Python 2)代码。在任务的上下文之外,我想创建一个同样在Python3中运行的代码版本,但在Python3中让客户机以同样的方式工作时遇到了问题 更改服务器和客户端 最初,服务器只需要很少的更改,我就可以让它工作了。我的服务器代码如下: #!/usr/

关于我的问题,我是一名计算机专业的学生,第一次开始学习Python。在此之前,我主要使用Java,现在我最熟悉Java约定和实践

背景 套接字编程的分配要求我们在机器上本地的服务器和客户端之间发送字符串。我们提供了实例化服务器和客户机的示例(Python 2)代码。在任务的上下文之外,我想创建一个同样在Python3中运行的代码版本,但在Python3中让客户机以同样的方式工作时遇到了问题

更改服务器和客户端 最初,服务器只需要很少的更改,我就可以让它工作了。我的服务器代码如下:

#!/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()
我无法将客户端转换为在Python3中运行和运行的代码。我已经尝试深入研究这个问题,但其他在线资源对我没有帮助(或者至少在我的经验水平上)。我的服务器代码如下

#!/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
并读取后,我对其进行了更改。我仍然不确定为什么这样做有效或者为什么我必须这样做(尽管我希望得到一个解释)

现在,当我运行客户机代码时,即使使用
sendto()
,我也会在服务器上得到相同的
TypeError
,但我不确定如何在Python 3中解决这个问题。我为服务器接收的stacktrace如下所示(我在客户机上得到一个断开的管道):

$python3 mail\u server.py
由('127.0.0.1',41866'连接
回溯(最近一次呼叫最后一次):
文件“mail_server.py”,第14行,在
conn.sendto(“欢迎使用服务器!”,(主机、端口))
TypeError:需要类似字节的对象,而不是“str”
我做错了什么?我怎样才能在Python3中工作?背景背景说明为什么这会特别有用,因为我认为我的问题的一部分是,我不明白为什么一开始就需要改变。谢谢

不要在流套接字上使用
sendto()
。一旦连接了套接字(对于流套接字,在连接之后才能进行任何数据传输),就无法指定目标,它总是发送到它所连接的远程地址/端口

因此,请使用
send()
sendall()


sendto()
用于数据报套接字,而不是流套接字。使用流套接字,您不需要告诉它发送到哪里,因为流已经连接到特定的端点。@Barmar我明白了。那么,我怎样才能为这个程序的应用程序创建一个流套接字呢?我是否应该做一些不同的事情,或者我是否需要使用
sendall()
对其进行更改以使其正常工作?
sock.accept()
返回流套接字,您不需要做任何特殊操作。只需使用
conn.send()
conn.sendall()
。你说你从
sendall
改为
sendto
,是因为你在另一个问题中读到了一些东西。我在那个问题上看不到任何东西表明你应该这样做。它说使用
message.encode()
message.decode()
来解决他们遇到的问题。
$ 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'
socket.sendall("Hello world".encode());