gpt4 book ai didi

python - 如何使用无阻塞套接字进行connect()?

转载 作者:行者123 更新时间:2023-12-03 11:53:58 27 4
gpt4 key购买 nike

在Python中,我想在已设置为非阻塞的套接字上使用socket.connect()。当我尝试执行此操作时,该方法始终会抛出BlockingIOError。当我忽略该错误(如下所示)时,程序将按预期执行。当我将套接字连接后设置为非阻塞时,没有任何错误。当我使用select.select()来确保套接字可读或可写时,我仍然会收到错误消息。

testserver.py

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
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
$ python testserver.py
--> From the client

第2终端
$ 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.
如何使用设置为非阻塞的套接字正确连接()?我可以使connect()处于非阻塞状态吗?还是仅忽略该错误是否合适?

最佳答案

这里的技巧是,当选择完成的第一次,那么你需要再次调用sock.connect。直到您从connect收到成功的返回状态,套接字才被连接。

在对select的第一次调用完成后,只需添加以下两行:

print("first select completed")
sock.connect((host, port))

编辑:

跟进。声明需要对 sock.connect进行额外的调用是错误的。但是,如果您希望在自己的代码路径中处理连接失败,这是发现对 connect的原始非阻塞调用是否成功的好方法。

下面介绍了用C代码实现此目标的传统方法: Async connect and disconnect with epoll (Linux)

这涉及到调用 getsockopt。您也可以在python中执行此操作,但是从 sock.getsockopt返回的结果是 bytes对象。而且,如果它表示故障,则需要将其转换为整数 errno值,并将其映射到字符串(或异常,或将问题传达给外界的任何条件)。再次调用 sock.connect已将 errno值映射到适当的异常。

解决方案2:
您也可以简单地将调用 sock.setblocking(0)推迟到连接完成之后。

关于python - 如何使用无阻塞套接字进行connect()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36092580/

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