如何关闭一个阻塞的套接字同时其正在等待接收数据?

5 投票
4 回答
7205 浏览
提问于 2025-04-17 03:12

我有一个服务,它使用阻塞套接字来接收数据。我的问题是,如果套接字还在等待数据,我不知道该怎么正确关闭它。下面是我打开套接字并等待数据的简短代码片段:我不想实现超时,因为根据Python的文档,使用makefile时套接字必须是阻塞的。

我可能完全搞错了,因为我刚开始学习使用套接字编程。

补充说明:

需要注意的是,我无法改变服务器的运行方式。

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
reader = s.makefile("rb")
line = reader.readline()

4 个回答

1

我认为,如果你直接从另一个线程关闭了一个连接,那么正在尝试读取这个连接的线程就会出错。如果你没有多个线程,那么你需要重新调整代码,使用非阻塞模式(在打开连接时使用选项 os.O_NONBLOCK)。

6

这里有一个很简单的解决办法。假设你有一个套接字(socket)和一个读取文件对象,比如说 rfile = socket.makefile('rb')。为了让 rfile.readline() 在套接字关闭时立即返回,你需要在一个单独的线程中执行以下操作:

socket.shutdown(socket.SHUT_RDWR)
socket.close()

调用 socket.shutdown() 会让 rfile.readline() 返回一个空的 strbytes,这取决于你使用的Python版本(2.x或3.x)。

2

关闭这个连接的一种方法是请求服务器来关闭它。

如果服务器关闭了客户端的连接,客户端会收到一个“对方重置连接”的错误,这可能会导致接收数据时出现问题。

另一种方法是不要使用 readline(),而是给你的连接设置一个超时时间(如果一直等下去,可能会一直等下去……)。

撰写回答