非阻塞连接 [英] Non-Blocking Connect

查看:50
本文介绍了非阻塞连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题不仅限于 Python.它是一个通用的套接字问题.我有一个非阻塞套接字并想连接到一台可访问的机器 - 在另一侧端口不存在.为什么 select(...) 无论如何都会成功?我期待超时.sock.send(...) 因管道损坏而失败.select(...)后如何判断socket是否真的连接上了?提前致谢.

导入socket、errno、os、time、select袜子 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)sock.setblocking(0)错误 = sock.connect_ex(('192.168.178.21', 12345))ready_to_read, ready_to_write, in_error = select.select([], [sock], [], timeout=5)#ready_to_write 设置即使 192.168.178.21:12345 不存在.sock.setblocking(1)sock.send('foo') #这个失败袜子.关闭()

解决方案

尝试检查返回值.这是我在类似情况下得到的:

<预><代码>>>>导入套接字、错误号、操作系统、时间、选择>>>袜子 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)>>>sock.setblocking(0)>>>错误 = sock.connect_ex(('10.0.0.1', 12345))>>>导入错误号>>>打印 errno.errorcode[err]进展>>>打印 sock.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)61>>>打印 errno.errorcode[61]拒绝

select() 调用可能正在返回,因为套接字上存在异常情况 - 即其连接被拒绝.

如果我这样做,select() 会立即返回:

<预><代码>>>>ready_to_read, ready_to_write, in_error = select.select([], [sock], [])

有趣的是,返回值与您传入的完全匹配(如果您有多个套接字,则可能会有所不同):

<预><代码>>>>打印错误[]>>>打印ready_to_read[]>>>打印 ready_to_write[]

select() 的设计者期望你在循环中运行 select(),如果在你尝试写入时套接字返回错误,请将其删除写入失败时的列表.

所以你有几个选择,在我的脑海里:

  • 等到您尝试读取套接字并失败,然后采取适当的措施.
  • 使用 getsockopt() 就像我上面所做的那样,在尝试对其执行任何操作之前检查套接字是否正常或处于错误状态.

This question is not limited to Python. Its a general socket question. I have a non-blocking socket and want to connect to a machine which is reachable - on the other side the port does not exist. Why does select(...) succeed anyway? I expected a timeout. sock.send(...) fails with a broken pipe. How can I determine if the socket is really connected after select(...)? Thanks in advance.

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()

解决方案

Try checking the return values. Here's what I get in a similar situation:

>>> import socket, errno, os, time, 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

The select() call is probably returning because there was an exceptional condition on the socket - that is, its connection was refused.

If I do this, the select() returns immediately:

>>> ready_to_read, ready_to_write, in_error = select.select([], [sock], [])

And interestingly enough, the return values match exactly what you passed in (if you had more than one socket, that would likely be different):

>>> print in_error
[]
>>> print ready_to_read
[]
>>> print ready_to_write
[<socket._socketobject object at 0x10ccd0980>]

The designers of select() are expecting you to run select() in a loop, and if a socket returns an error when you attempt the write, remove it from the list when the write fails.

So you have a couple of options, off the top of my head:

  • Wait until you try to read the socket and fail, then take the appropriate action.
  • Use getsockopt() as I did above to check if the socket is OK, or is in an error state, before attempting to do anything with it.

这篇关于非阻塞连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆