首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用非阻塞套接字连接()?

如何用非阻塞套接字连接()?
EN

Stack Overflow用户
提问于 2016-03-18 19:15:27
回答 1查看 8.1K关注 0票数 5

在Python中,我希望在我设置为非阻塞的套接字上使用socket.connect()。当我尝试这样做时,这个方法总是抛出一个BlockingIOError。当我忽略错误时(如下所示),程序将按预期执行。当我将套接字在连接后设置为非阻塞时,没有错误.当我使用select.select()来确保套接字是可读的或可写的时,我仍然会得到错误。

testserver.py

代码语言:javascript
复制
import socket
import select

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setblocking(0)

host = socket.gethostname()
port = 1234

sock.bind((host, port))
sock.listen(5)

while True:
    select.select([sock], [], [])
    con, addr = sock.accept()
    message = con.recv(1024).decode('UTF-8')
    print(message)

testclient.py

代码语言:javascript
复制
import socket
import select

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setblocking(0)

host = socket.gethostname()
port = 1234

try:
    sock.connect((host, port))
except BlockingIOError as e:
    print("BlockingIOError")

msg = "--> From the client\n"

select.select([], [sock], [])
if sock.send(bytes(msg, 'UTF-8')) == len(msg):
    print("sent ", repr(msg), " successfully.")

sock.close()

终端1

代码语言:javascript
复制
$ python testserver.py
--> From the client

终端2

代码语言:javascript
复制
$ python testclient.py
BlockingIOError
sent  '--> From the client\n'  successfully.

除了第一个connect()上的BlockingIOError之外,这段代码正常工作。错误的文档如下:Raised when an operation would block on an object (e.g. socket) set for non-blocking operation.

如何正确地连接()与套接字设置为非阻塞?我能使连接()非阻塞吗?还是直接忽略错误是合适的呢?

EN

回答 1

Stack Overflow用户

发布于 2021-10-14 19:56:47

当使用带有非阻塞套接字的socket.connect时,最初希望得到一个BlockingIOError。有关原因的解释,请参见TCP Connect error 115 Operation in Progress What is the Cause?。基本上,套接字还没有准备好并引发BlockingIOError: [Errno 115] Operation now in progress,也称为EINPROGRESS

解决方案是要么捕获并忽略异常,要么使用socket.connect_ex而不是socket.connect,因为该方法不会引发异常。特别要注意Python文档中描述的最后一句:

socket.connect_ex(address)connect(address)类似,但是返回一个错误指示符,而不是为C级connect()调用返回的错误引发异常(其他问题,如“主机未找到”,仍然会引发异常)。如果操作成功,则错误指示符为0,否则为errno变量的值。这对于支持异步连接(例如.)很有用。

来源:ex

如果要继续使用socket.connect,可以捕获并忽略负责任的EINPROGRESS错误:

代码语言:javascript
复制
>>> import socket
>>> 
>>> # bad
>>> s = socket.socket()
>>> s.setblocking(False)
>>> s.connect(("127.0.0.1", 8080))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
BlockingIOError: [Errno 115] Operation now in progress
>>> 
>>> # good
>>> s = socket.socket()
>>> s.setblocking(False)
>>> try:
...     s.connect(("127.0.0.1", 8080))
... except OSError as exc:
...     if exc.errno != 115:  # EINPROGRESS
...         raise
... 
>>> 
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36092580

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档