【问题标题】:Async DNS query function can only be called once per session每个会话只能调用一次异步 DNS 查询功能
【发布时间】:2021-12-06 17:58:17
【问题描述】:

可能这是一个愚蠢的问题,我知道这一定很琐碎,并且可能已经被问过很多次,但我不知道答案,而且我通过谷歌找到的答案都没有解决问题。

问题其实很简单,我用的例子代码来自https://pypi.org/project/async-dns/:

import asyncio
from async_dns.core import types, Address
from async_dns.resolver import DNSClient

async def query():
    client = DNSClient()
    res = await client.query('www.google.com', types.A,
                             Address.parse('8.8.8.8'))
    print(res)
    print(res.aa)

asyncio.run(query())

而且它只能被调用一次而不会引发各种异常,其中之一是:RuntimeError: Event loop is closed

我尝试了"Asyncio Event Loop is Closed" when getting loop 的建议,但到目前为止没有运气:

Python 3.10.0 (tags/v3.10.0:b494f59, Oct  4 2021, 19:00:18) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import asyncio
>>> from async_dns.core import types, Address
>>> from async_dns.resolver import DNSClient
>>>
>>> async def query():
...     client = DNSClient()
...     res = await client.query('www.google.com', types.A,
...                              Address.parse('8.8.8.8'))
...     print(res)
...     print(res.aa)
...
>>> asyncio.run(query())
<DNSMessage type=1 qid=35499 r=0 QD=[<Record type=request qtype=A name=www.google.com>] AN=[<Record type=response qtype=A name=www.google.com ttl=157 data=<a: 108.160.163.108>>] NS=[] AR=[]>
0
>>> asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
>>> loop = asyncio.new_event_loop()
>>> loop.run_until_complete(query())
Fatal write error on datagram transport
protocol: <async_dns.request.udp.CallbackProtocol object at 0x0000022AEE2491B0>
transport: <_ProactorDatagramTransport fd=528 read=<_OverlappedFuture cancelled>>
Traceback (most recent call last):
  File "C:\Program Files\Python310\lib\asyncio\proactor_events.py", line 528, in _loop_writing
    self._write_fut = self._loop._proactor.sendto(self._sock,
AttributeError: 'NoneType' object has no attribute 'sendto'
Traceback (most recent call last):
  File "C:\Program Files\Python310\lib\asyncio\proactor_events.py", line 528, in _loop_writing
    self._write_fut = self._loop._proactor.sendto(self._sock,
AttributeError: 'NoneType' object has no attribute 'sendto'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Program Files\Python310\lib\asyncio\base_events.py", line 641, in run_until_complete
    return future.result()
  File "<stdin>", line 3, in query
  File "C:\Program Files\Python310\lib\site-packages\async_dns\resolver\client.py", line 35, in query
    return await task
  File "C:\Program Files\Python310\lib\site-packages\async_dns\resolver\client.py", line 42, in _query
    res = await asyncio.wait_for(self._request(req, addr), self.timeout)
  File "C:\Program Files\Python310\lib\asyncio\tasks.py", line 447, in wait_for
    return fut.result()
  File "C:\Program Files\Python310\lib\site-packages\async_dns\resolver\client.py", line 51, in _request
    data = await request(req, addr, self.timeout)
  File "C:\Program Files\Python310\lib\site-packages\async_dns\request\udp.py", line 111, in request
    data = await dispatcher.send(req, addr, timeout)
  File "C:\Program Files\Python310\lib\site-packages\async_dns\request\udp.py", line 84, in send
    return await self._send(req.pack(), (host, port or 53), timeout)
  File "C:\Program Files\Python310\lib\site-packages\async_dns\request\udp.py", line 77, in _send
    return await self.protocol.write_data(data, addr, timeout)
  File "C:\Program Files\Python310\lib\site-packages\async_dns\request\udp.py", line 53, in write_data
    self.transport.sendto(data, addr)
  File "C:\Program Files\Python310\lib\asyncio\proactor_events.py", line 501, in sendto
    self._loop_writing()
  File "C:\Program Files\Python310\lib\asyncio\proactor_events.py", line 534, in _loop_writing
    self._fatal_error(exc, 'Fatal write error on datagram transport')
  File "C:\Program Files\Python310\lib\asyncio\proactor_events.py", line 131, in _fatal_error
    self._force_close(exc)
  File "C:\Program Files\Python310\lib\asyncio\proactor_events.py", line 151, in _force_close
    self._loop.call_soon(self._call_connection_lost, exc)
  File "C:\Program Files\Python310\lib\asyncio\base_events.py", line 745, in call_soon
    self._check_closed()
  File "C:\Program Files\Python310\lib\asyncio\base_events.py", line 510, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
>>> asyncio.set_event_loop(asyncio.new_event_loop())
>>> asyncio.get_event_loop()
<stdin>:1: DeprecationWarning: There is no current event loop
<_WindowsSelectorEventLoop running=False closed=False debug=False>
>>> asyncio.run(query())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Program Files\Python310\lib\asyncio\runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "C:\Program Files\Python310\lib\asyncio\base_events.py", line 641, in run_until_complete
    return future.result()
  File "<stdin>", line 3, in query
  File "C:\Program Files\Python310\lib\site-packages\async_dns\resolver\client.py", line 35, in query
    return await task
  File "C:\Program Files\Python310\lib\site-packages\async_dns\resolver\client.py", line 42, in _query
    res = await asyncio.wait_for(self._request(req, addr), self.timeout)
  File "C:\Program Files\Python310\lib\asyncio\tasks.py", line 447, in wait_for
    return fut.result()
  File "C:\Program Files\Python310\lib\site-packages\async_dns\resolver\client.py", line 51, in _request
    data = await request(req, addr, self.timeout)
  File "C:\Program Files\Python310\lib\site-packages\async_dns\request\udp.py", line 111, in request
    data = await dispatcher.send(req, addr, timeout)
  File "C:\Program Files\Python310\lib\site-packages\async_dns\request\udp.py", line 84, in send
    return await self._send(req.pack(), (host, port or 53), timeout)
  File "C:\Program Files\Python310\lib\site-packages\async_dns\request\udp.py", line 77, in _send
    return await self.protocol.write_data(data, addr, timeout)
  File "C:\Program Files\Python310\lib\site-packages\async_dns\request\udp.py", line 53, in write_data
    self.transport.sendto(data, addr)
  File "C:\Program Files\Python310\lib\asyncio\proactor_events.py", line 497, in sendto
    self._buffer.append((bytes(data), addr))
AttributeError: 'NoneType' object has no attribute 'append'
>>>

如何解决?

【问题讨论】:

    标签: python python-3.x asynchronous python-asyncio


    【解决方案1】:

    在这种情况下,通常最好去项目的 GitHub 并在问题中搜索错误消息:

    https://github.com/gera2ld/async_dns/issues?q=is%3Aissue+Event+loop+is+closed

    它给了我们一个结果,解决方案在最后一条评论中:

    https://github.com/gera2ld/async_dns/issues/26#issuecomment-844850252

    最终代码:

    import asyncio
    from async_dns.core import types, Address
    from async_dns.resolver import DNSClient
    from async_dns.request import clean
    
    
    async def query():
        client = DNSClient()
        res = await client.query("www.google.com", types.A, Address.parse("8.8.8.8"))
        print(res)
        print(res.aa)
        clean()
    
    
    asyncio.run(query())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-01
      • 1970-01-01
      • 2014-03-30
      • 1970-01-01
      相关资源
      最近更新 更多