Python UDP 套接字在 recvfrom() 时立即报错

2 投票
2 回答
2399 浏览
提问于 2025-04-20 18:50

我正在尝试用Python做一些简单的套接字编程。我有一个UDP服务器,它可以接收输入并发送响应。不过,我在客户端的代码上遇到了一些麻烦。

sock = socket.socket(
    socket.AF_INET, socket.SOCK_DGRAM
)
sock.bind(('0.0.0.0', 0))
sock.settimeout(2)
sock.sendto(json.dumps({
    'operation': operation,
    'operands': [operand1, operand2]
}), (host, port))

print sock.recvfrom(4096)

当服务器正常运行时,这段代码工作得很好。但是,当我尝试在没有服务器运行的情况下运行它时,代码会立即抛出一个异常,而不是在recvfrom()上等待。

socket.error: [Errno 10054] An existing connection was forcibly closed by the remote host

我希望的功能是能在一段时间后超时。有没有人能解释一下我哪里做错了?我在服务器代码中使用recvfrom,它是可以阻塞的,所以我有点困惑,为什么会有这样的区别。

2 个回答

0

这可能有很多原因。

Socket错误[10054]表示连接被对方重置。

这意味着远程主机强行关闭了一个已经存在的连接。通常情况下,这种情况发生在远程主机上的应用程序突然停止、主机重启、主机或远程网络接口被禁用,或者远程主机使用了强制关闭(想了解更多可以查看setsockopt中关于SO_LINGER选项的内容)。如果在某些操作进行时,连接因为保持活动状态而检测到故障,也可能导致这个错误。正在进行的操作会因为WSAENETRESET而失败,而后续的操作则会因为WSAECONNRESET而失败。

想了解更多细节,可以查看这个链接

你需要深入调查一下,找出到底发生了什么。我无法访问你的环境,所以不能确定真正的问题是什么。希望这些信息对你有帮助。

1

之前的回答大部分不适用,因为你使用的是SOCK_DGRAM类型,也就是UDP套接字。UDP是一种无连接的服务,尽管错误信息中提到了连接。这个异常是因为目标主机在收到你的sendto数据包后发来的通知,告诉你那个端口无法访问;这个通知的处理(可能甚至会到达)是在你调用recvfrom之前。没有自动重试的机制;你需要自己再次尝试recvfrom(也许还要重新尝试sendto),并自己实现想要的超时功能。

撰写回答