python - 如何从loop.sock_recv()函数捕获连接重置错误?

标签 python sockets exception python-asyncio

我试图从客户端套接字读取字节时尝试从loop.sock_recv函数捕获连接重置错误。我正在测试一种情况,当服务器在特定超时后关闭连接时,sock_recv(client_socket,max_rec)函数会按预期引发连接重置错误,但我无法在代码中捕获它。相反,如果我用try/finally替换try/except,则效果更好,但并不总是能给出预期的答案。

 try:
            done, pending = await asyncio.wait([loop.sock_recv(client_sock, max_rec)], timeout = 7)

        except ConnectionResetError:
            log.info(f"Got the connection reset which means the server socket closed the connection after {timeout} seconds")
            is_connection_reset = True
日志是
[[0m ERROR    16:43:05| asyncio                        - Task exception was never retrieved
[[36mtest-client_1  |^[[0m future: <Task finished name='Task-67' coro=<BaseSelectorEventLoop.sock_recv() done, defined at /usr/local/lib/python3.8/asyncio/selector_events.py:349> exception=ConnectionResetError(104, 'Connection reset by peer')>(base_events.py, line 1707)
[[36mtest-client_1  |[[0m Traceback (most recent call last):
[[36mtest-client_1  |[[0m   File "/usr/local/lib/python3.8/asyncio/selector_events.py", line 368, in sock_recv
[[36mtest-client_1  |[[0m     return await fut
[[36mtest-client_1  |[[0m   File "/usr/local/lib/python3.8/asyncio/selector_events.py", line 379, in _sock_recv
[[36mtest-client_1  |[[0m     data = sock.recv(n)
[[36mtest-client_1  |[[0m ConnectionResetError: [Errno 104] Connection reset by peer

最佳答案

您应该将asyncio.wait([...], timeout=7)替换为asyncio.wait_for:

try:
    data = await asyncio.wait_for(
        loop.sock_recv(client_sock, max_rec), 7)
except ConnectionResetError:
    ... handle connection reset
except asyncio.TimeoutError:
    ... handle timeout
asyncio.wait_for(x, 7)asyncio.wait([x], timeout=7)之间的区别在于,如果超时,wait_for将取消等待。另一方面,asyncio.wait()将使其在后台运行(并在pending集中返回它)。
在您的情况下,最有可能发生的情况是sock_recv在超过7秒后会升起ConnectionResetError。如所写,您的代码仅在前7秒内发生错误时处理该错误。如果稍后发生,它将在后台任务中引发并由默认异常处理程序报告。
顺便提一句,您可能不应该直接使用sock_recv。这是一个低级API,只有新事件循环的实现者才需要关心。应用程序代码应改为使用 asyncio.open_connection

关于python - 如何从loop.sock_recv()函数捕获连接重置错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62839066/

相关文章:

c - 套接字编程中的 bzero

java - 异常处理 try-catch 语句字符串长度

java - 静态变量未初始化时抛出异常

java - 相关的Java程序和Python程序是否应该共存于同一个git repo中?

python - 从字节字符串创建 ipaddr-py IPv6Address

python - 如何使用 Plotly 绘制循环的局部变量

python - 在 Python 中匹配行首的字符串

java - 使用套接字从 Android 设备连接到 ESP8266

c - libuv : src port of response not same as port on which process is listening

java - 有时 IoException :Mark Invalid Jsoup Android App