当服务器不发回数据时,为什么 `socket.recv()` 会停止?

Patricia Arquette
发布: 2024-11-22 22:33:26
原创
865 人浏览过

Why Does `socket.recv()` Stall When the Server Doesn't Send Data Back?

了解套接字行为:为什么 Socket.recv() 在没有发送数据的情况下停止

Python 套接字与 TCP 连接一样,表现为数据流在客户端和服务器之间流动。本文深入探讨了修改数据传输后,socket.recv()调用无法返回数据的原因。

Echo Server 示例

考虑官方文档中的 Python echo 服务器示例。该服务器侦听传入连接、接收数据并将其回显给客户端。以下代码片段复制了原始服务器行为:

import socket

HOST = ''
PORT = 50007 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)

conn, addr = s.accept()
print('Connected by', addr)

while True:
    data = conn.recv(1024)
    if not data: break
    conn.sendall(data)
conn.close()
登录后复制

更改服务器行为

将代码修改为不将数据发送回客户端时会出现此问题:

while True:
    data = conn.recv(1024)
    if not data: break
conn.close()
登录后复制

在这段修改后的代码中,while循环不断地从客户端接收数据,但服务器却从不发送数据 后退。这会导致客户端在 socket.recv() 调用处无限期地停止。

理解通信流程

TCP 套接字不维护一对一关系不同端点上的发送和接收呼叫之间。相反,协议定义了通信规则。在这种情况下,原始的回显服务器实现了一个规则,即服务器将回显接收到的数据,直到客户端关闭连接。

当服务器行为发生更改时,规则实际上已被修改。服务器现在只接收数据并丢弃它,直到客户端关闭连接。服务器永远不会将数据发送回客户端。

调整客户端行为

要使用修改后的服务器,客户端必须调整其行为。由于服务器不再主动发送数据,客户端认为收到回数据表明连接已完成。为了实现这一点,客户端应该关闭其连接的传出端,以向服务器发出信号已完成发送数据。然后,客户端可以执行多个 recv 调用来处理传入数据的任何潜在碎片。

更新的代码

下面是服务器和客户端的更新代码,遵守修改后的规则通信:

服务器:

import socket

HOST = ''
PORT = 50007 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(1)

conn, addr = s.accept()
print('Connected by', addr)

while True:
    data = conn.recv(1024)
    if not data: break
conn.sendall(b'ok')
conn.shutdown(socket.SHUT_WR)
conn.close()
登录后复制

客户端:

import socket

HOST = 'localhost'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(b'Hello, world')
s.shutdown(socket.SHUT_WR)
data = b''
while True:
    buf = s.recv(1024)
    if not buf:
        break
    data += buf
s.close()
print('Received', repr(data))
登录后复制

通过了解基于流的本质TCP套接字并相应地调整通信规则,可以解决socket.recv()在没有数据的情况下停止的问题已发送。

以上是当服务器不发回数据时,为什么 `socket.recv()` 会停止?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板