簡體   English   中英

異步 DNS 查詢 function 每個 session 只能調用一次

[英]Async DNS query function can only be called once per session

可能這是一個愚蠢的問題,我知道這一定很瑣碎,並且可能已經被問過很多次,但我不知道答案,而且我通過谷歌找到的答案都沒有解決問題。

問題很簡單,我使用了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”的建議,但到目前為止還沒有運氣:

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'
>>>

如何解決?

在這種情況下,將 go 到項目的 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())

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM