【发布时间】:2011-02-05 02:43:58
【问题描述】:
当我关闭连接一端的套接字时,另一端第二次发送数据时出错,但不是第一次:
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("localhost", 12345))
server.listen(1)
client = socket.create_connection(("localhost",12345))
sock, addr = server.accept()
sock.close()
client.sendall("Hello World!") # no error
client.sendall("Goodbye World!") # error happens here
我尝试设置 TCP_NODELAY,使用 send 而不是 sendall,检查 fileno(),我找不到任何方法让第一次发送引发错误,甚至无法在事后检测到它失败. 编辑:在sock.close 之前调用sock.shutdown 没有帮助。 编辑#2:即使在关闭之后和写入之前添加time.sleep 也没有关系。 编辑#3:检查send 返回的字节数没有帮助,因为它总是返回消息中的字节数。
因此,如果我想检测错误,我能想出的唯一解决方案是在每个 sendall 后面加上 client.sendall(""),这会引发错误。但这似乎很骇人听闻。我使用的是 Linux 2.6.x,因此即使解决方案仅适用于该操作系统,我也会很高兴。
【问题讨论】:
-
我遇到了同样的问题。您最终是如何解决代码中的问题的?
-
@HighCommander:我最终在每个
send之后添加了一个client.sendall(""),这在技术上不能保证会出错,但适用于我的程序,给出了我正在做的时间和细节.这是不优雅的,我真的希望有一种方法可以访问底层 TCP 套接字状态,但可惜在 Python 或 C 中似乎没有。 -
当客户端和服务器在不同的机器上时,这对你有用吗?它不适合我,在这种情况下 sendall() 会成功。
-
@HighCommander:这对我在讨论
localhost时有用,但我没有在多台机器上尝试过,实际上我不希望它在这些情况下是可靠的,因为它会需要更长的时间来检测故障。如果您在本地 Intranet 上运行,并且往返时间相当一致,并且性能不是一个大问题,那么您可以在第二次发送之前添加一个短暂的睡眠。