如何处理可变长度消息并自动关闭套接字?

时间:2017-09-02 22:57:37

标签: python python-3.x sockets

我有以下情况:

服务器

Server listening on 172.16.0.110:8081
Incoming connection from 172.16.0.110:62388
Received "Lorem Ipsum" from 172.16.0.110:62388

客户端

Server reply: I got the message "Lorem Ipsum"

我首先启动服务器,然后启动客户端,并获得以下日志:

服务器

{{1}}

客户端

{{1}}

我想获得服务器回复然后客户端应该完成,但服务器和客户端都进入无限循环并继续运行。为什么以及如何解决这个问题?我在IPv4网络中使用Windows 10 x64上的Python 3.6.0。

2 个答案:

答案 0 :(得分:3)

您必须定义一个协议,该协议只是消息交换和格式化的规则,以及消息边界的通信方式。看起来您只是希望客户端发送一些数据并读取服务器响应。您可以通过在sock.shutdown(socket.SHUT_WR)之后调用sock.sendall(...)来关闭客户端连接的写半部分来实现此目的。

在服务器端,这是同一连接的读取一半,服务器将其检测为EOF,导致socket.recv()返回零长度字节对象。

对于要在同一连接上发送多条消息的更复杂的协议,必须使用不同的策略。二进制协议的一个简单示例是发送4个字节,表示消息的字节长度,然后为后续消息本身发送那么多字节。

答案 1 :(得分:0)

一种方法是为套接字设置超时,以便在等待使用socket.settimeout()的回复时不会永久阻止,如下所示:

sock = socket.socket()
sock.connect(server_address)
sock.sendall('Lorem Ipsum'.encode())
sock.settimeout(5.0) # sets timeout to 5 seconds

while True:
    data = sock.recv(buffer_size)
    if not data:
        break
    print(data.decode())

sock.close()