gpt4 book ai didi

python - 如果在发生超时之前没有收到数据,Python 的 socket.recv() 会为非阻塞套接字返回什么?

转载 作者:IT老高 更新时间:2023-10-28 20:31:48 24 4
gpt4 key购买 nike

基本上,我在几个地方读到 socket.recv() 将返回它可以读取的任何内容,或者一个表明对方已关闭的空字符串(官方文档没有'甚至没有提到连接关闭时它返回的内容......太棒了!)。这对于阻塞套接字来说很好而且花花公子,因为我们知道 recv() 只在实际有东西要接收时才返回,所以当它返回一个空字符串时,它必须 意思是对方已经关闭了连接,对吧?

好的,好的,但是当我的套接字非阻塞时会发生什么?我已经搜索了一下(可能还不够,谁知道?)并且无法弄清楚如何判断对方何时使用非阻塞套接字关闭了连接。似乎没有方法或属性可以告诉我们这一点,并且将 recv() 的返回值与空字符串进行比较似乎完全没用......难道只有我有这个问题吗?

举个简单的例子,假设我的套接字超时设置为 1.2342342(你喜欢这里的任何非负数)秒,我调用 socket.recv(1024),但另一端没有在 1.2342342 秒期间不要发送任何内容。 recv() 调用将返回一个空字符串,我不知道连接是否仍然存在......

最佳答案

在没有可用数据的非阻塞套接字的情况下,recv 将抛出 socket.error 异常,并且该异常的值将具有 EAGAIN 或 EWOULDBLOCK 的 errno。示例:

import sys
import socket
import fcntl, os
import errno
from time import sleep

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1',9999))
fcntl.fcntl(s, fcntl.F_SETFL, os.O_NONBLOCK)

while True:
try:
msg = s.recv(4096)
except socket.error, e:
err = e.args[0]
if err == errno.EAGAIN or err == errno.EWOULDBLOCK:
sleep(1)
print 'No data available'
continue
else:
# a "real" error occurred
print e
sys.exit(1)
else:
# got a message, do something :)

在您通过 socket.settimeout(n) 超时启用非阻塞行为的情况下,情况会有所不同。或 socket.setblocking(False) .在这种情况下,仍然会引发 socket.error,但在超时的情况下,异常的伴随值始终是设置为“超时”的字符串。因此,要处理这种情况,您可以这样做:

import sys
import socket
from time import sleep

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1',9999))
s.settimeout(2)

while True:
try:
msg = s.recv(4096)
except socket.timeout, e:
err = e.args[0]
# this next if/else is a bit redundant, but illustrates how the
# timeout exception is setup
if err == 'timed out':
sleep(1)
print 'recv timed out, retry later'
continue
else:
print e
sys.exit(1)
except socket.error, e:
# Something else happened, handle error, exit, etc.
print e
sys.exit(1)
else:
if len(msg) == 0:
print 'orderly shutdown on server end'
sys.exit(0)
else:
# got a message do something :)

正如评论中所指出的,这也是一个更便携的解决方案,因为它不依赖于操作系统特定的功能来将套接字置于非阻塞模式。

recv(2)python socket了解更多详情。

关于python - 如果在发生超时之前没有收到数据,Python 的 socket.recv() 会为非阻塞套接字返回什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16745409/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com