首页  >  文章  >  后端开发  >  为什么删除从 Python Socket 服务器回显的数据会导致 `socket.recv()` 在后续调用中不返回任何内容?

为什么删除从 Python Socket 服务器回显的数据会导致 `socket.recv()` 在后续调用中不返回任何内容?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-11-27 03:37:22922浏览

Why Does Removing Data Echoing from a Python Socket Server Cause `socket.recv()` to Return Nothing on Subsequent Calls?

Python Socket:了解数据返回行为的影响

最初,官方文档中的 Python echo 服务器示例运行完美。然而,在修改代码以消除将数据发送回客户端后,出现了问题。第二次调用 socket.recv() 方法没有返回。

不同的实现,不同的结果

文档中的原始代码使用了一个 while 循环:

conn.sendall(data)

这一行暗示服务器会将收到的数据回显给客户端,直到客户端关闭其连接。

在修改后的代码中,行为更改如下:

break

当第二次调用 conn.recv(1024) 方法时,它会立即终止,没有留下可用的数据客户端。

TCP 流的本质

要理解这种行为,必须掌握 TCP 流的本质。它们以连续流传输数据,客户端和服务器操作之间没有直接关联。此外,协议决定了底层的通信规则。

在原始代码中,协议规定服务器将回显它收到的每个数据包,直到客户端关闭其传出连接。关闭后,服务器将关闭其套接字。

修改后的协议和客户端调整

修改后的代码引入了一个新协议,服务器将丢弃传入的数据,直到客户端关闭其传出连接。随后,服务器将发送“ok”并关闭其套接字。

为了让客户端使用这个新协议,有必要:

  1. 关闭客户端的传出连接指示完成。
  2. 实现多个 recv() 调用以解决数据中潜在的碎片问题

更新的服务器和客户端

以下更新的代码示例演示了修订后的协议实现:

服务器:

导入套接字<p>HOST = ''<br>PORT = 50007 <br>s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)<br>s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)<br>s.bind((主持人, PORT))<br>s.listen(1)</p><p>conn, addr = s.accept()<br>print('连接者', addr)</p><p>while True:</p><pre class="brush:php;toolbar:false">data = conn.recv(1024)
if not data: break

conn.sendall(b'ok')
conn.shutdown(socket.SHUT_WR)
conn.close()

客户端:

<预>导入插座

HOST = 'localhost'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall (你好, world')
s.shutdown(socket.SHUT_WR)
data = b''
while True:

data = conn.recv(1024)
if not data: break

s.close()
print('已收到' , repr(data))

通过这些修改后的实现,服务器有效地丢弃传入的数据,允许客户端在关闭后接收其响应。

以上是为什么删除从 Python Socket 服务器回显的数据会导致 `socket.recv()` 在后续调用中不返回任何内容?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn