Python 3套接字编程:使用sendall与sendto

时间:2016-10-19 19:16:24

标签: python sockets python-3.x networking

作为我的问题的背景,我是第一次开始使用Python的计算机学生。在此之前,我主要使用Java,我现在最熟悉Java约定和实践。

背景

套接字编程的赋值要求我们在服务器和客户端本地在机器上发送字符串。我们提供了实例化服务器和客户端的示例(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中使用它?关于为什么会这样做的背景背景会特别有用,因为我认为我的问题的一部分是我没有看到为什么这个改变是必要的。谢谢!

1 个答案:

答案 0 :(得分:2)

不要在流套接字上使用sendto()。一旦连接了套接字(并且使用流套接字,您无法在连接之后进行任何数据传输),您无法指定目标,它始终会发送到远程地址/端口它是连接的。

因此请使用send()sendall()

socket.sendall("Hello world".encode());