2016-06-29 2 views
0

새로운 asyncio 모듈을 Python 3.5.1에서 시험해보고 싶었습니다. 나는이 self.transport.sendto(self.message.encode())self.transport.close()의 순서에 의해 발생 생각Asyncio : 매우 간단한 쓰기 및 연결 해제 UDP 클라이언트의 문제

Traceback (most recent call last): 
    File "C:\Users\oxygen\Documents\GitProjects\tests\python\udp\client.py", line 
35, in <module> 
    loop.run_forever() 
    File "C:\Python35-32\lib\asyncio\base_events.py", line 295, in run_forever 
    self._run_once() 
    File "C:\Python35-32\lib\asyncio\base_events.py", line 1218, in _run_once 
    event_list = self._selector.select(timeout) 
    File "C:\Python35-32\lib\selectors.py", line 314, in select 
    r, w, _ = self._select(self._readers, self._writers, [], timeout) 
    File "C:\Python35-32\lib\selectors.py", line 305, in _select 
    r, w, x = select.select(r, w, w, timeout) 
OSError: [WinError 10038] an operation was attempted on something that is not a socket 

:이 프로그램을 실행할 때

import asyncio 

class EchoClientProtocol: 
    def __init__(self, message, loop): 
     self.message = message 
     self.loop = loop 
     self.transport = None 

    def connection_made(self, transport): 
     self.transport = transport 
     print('Send:', self.message) 
     self.transport.sendto(self.message.encode()) 
     self.transport.close() 

    def datagram_received(self, data, addr): 
     print("Received:", data.decode()) 

     print("Close the socket") 
     #self.transport.close() 

    def error_received(self, exc): 
     print('Error received:', exc) 

    def connection_lost(self, exc): 
     print("Socket closed, stop the event loop") 
     loop = asyncio.get_event_loop() 
     loop.stop() 

loop = asyncio.get_event_loop() 
message = "Hello World!" 
connect = loop.create_datagram_endpoint(
    lambda: EchoClientProtocol(message, loop), 
    remote_addr=('127.0.0.1', 9999)) 
transport, protocol = loop.run_until_complete(connect) 
loop.run_forever() 
transport.close() 
loop.close() 

, 인터프리터가 나에게 제공 : 여기 내 테스트 코드입니다. 올바르게 이해하면 sendto 메서드는 비동기이며 close 메서드를 호출하여 소켓을 닫은 후에 실제로 호출됩니다. 이 문제를 해결할 방법이 있습니까?

답변

0

DatagramTransport (실제로 _SelectorDatagramTransport) 스케줄을 연결에서 두 가지 작업은 첫번째 프로토콜에서 주어진 connection_made이며, 두 번째 _read_ready (에 recvfrom)이다 - 순서 (https://github.com/python/asyncio/blob/master/asyncio/selector_events.py#L996)이다.

connection_made에서 수송을 닫았으므로 다음 작업 (_read_ready)이 실패합니다. 거기에서 self.transport.close()을 제거하십시오.

흥미로운 asyncio udp examples을 찾을 수 있습니다.

+0

안녕하세요, 귀하의 의견을 보내 주셔서 감사합니다. 내 코드는 실제로 연결된 예제의 편집 된 버전입니다. 독서 작업없이 연결을 여는 방법에 대한 도움을 좀주세요. 정말 연결을 설정하고, 데이터를 보내고 닫고 싶습니다. 문서에서 도움을 얻으려고했지만 [이 방법] (https://docs.python.org/3/library/asyncio-stream.html#asyncio.open_connection)이 발견되어 도움이 되었습니까? –

+0

UDP는 비 연결형 프로토콜입니다 (https://en.wikipedia.org/wiki/User_Datagram_Protocol). – kwarunek