前端之家收集整理的这篇文章主要介绍了
python – 非阻塞连接,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这个问题不仅限于Python.这是一个普通的插座问题.我有一个非阻塞套接字,并希望连接到可访问的机器 – 另一方面端口不存在.为什么选择(…)成功呢?我预计会超时. sock.send(…)因管道损坏而失败.如何在选择(…)后确定套接字是否真正连接?
提前致谢.
import socket,errno,os,time,select
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.setblocking(0)
err = sock.connect_ex(('192.168.178.21',12345))
ready_to_read,ready_to_write,in_error = select.select([],[sock],[],timeout=5)
#ready_to_write is set even 192.168.178.21:12345 does not exist.
sock.setblocking(1)
sock.send('foo') #this fails
sock.close()
@H_
404_11@最佳答案
尝试检查返回值.这是我在类似情况下得到的结果:
>>> import socket,select
>>> sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
>>> sock.setblocking(0)
>>> err = sock.connect_ex(('10.0.0.1',12345))
>>> import errno
>>> print errno.errorcode[err]
EINPROGRESS
>>> print sock.getsockopt(socket.SOL_SOCKET,socket.SO_ERROR)
61
>>> print errno.errorcode[61]
ECONNREFUSED
select()调用可能正在返回,因为套接字上存在异常情况 – 也就是说,它的连接被拒绝了.
如果我这样做,select()立即返回:
>>> ready_to_read,[])
有趣的是,返回值与您传入的内容完全匹配(如果您有多个套接字,则可能会有所不同):
>>> print in_error
[]
>>> print ready_to_read
[]
>>> print ready_to_write
[
select()的设计者期望您在循环中运行select(),如果套接字在您尝试写入时返回错误,则在写入失败时将其从列表中删除.
所以你有几个选择,在我的头顶:
>等到您尝试读取套接字并失败,然后采取适当的操作.
>在尝试对它执行任何操作之前,像上面一样使用getsockopt()来检查套接字是否正常,或者是否处于错误状态.