2016-07-25 5 views
0

먼저 asyncio 또는 그 패러다임에 완전히 익숙하다고 말해야합니다.asyncio를 사용하여 텔넷 클라이언트를 만드는 방법

그래서 나는 asyncio.open_connection()과 함께 asyncio (python 3.4) 클라이언트를 구현하여 TCP 소켓 (telnet)에서 요청을 보내고 응답을 읽고 다른 쪽에서 보낼 수있는 것을 수신 할 수 있습니다.

다른 말로하면 나는 초기화하는 양방향 통신이 필요하므로 클라이언트입니다. 그러나 StreamReaderStreamWriter을 사용하여 지금까지 찾은 모든 예제는 빈 줄을 읽은 후 루프를 중단해야했습니다. 또한 들어오는 메시지 (모든 메시지가 정확히 한 줄인 경우)는 상대방의 요청 또는 원본 메시지에 대한 응답입니다. 나는 이것이 작동 할 것이라고 생각하고있었습니다.

class MyHandler: 
    @asyncio.coroutine 
    def connect(self): 
     self.reader, self.writer = asyncio.open_connection('localhost', 2020) 

     while True: 
      msg = self.reader.readline() 
      if msg is None: 
       asyncio.sleep(1) 
       continue 
      self.handle_msg(msg) 

    @asyncio.coroutine 
    def request(self, msg): 
     self.writer.write(msg) 
     return self.reader.readline() 

if __name__ == '__main__': 
    h = MyHandler() 
    loop = asyncio.get_event_loop() 
    loop.run_until_complete(h.connect) 
    loop.close() 

이 질문을 만들 때만이 코드를 작성했습니다. 이제는 실행을 시작 했으므로 주요 지점에 도달하기 전에 실패합니다. 어떤 식 으로든 loop.run_until_complete(h.connect)TypeError: A Future or coroutine is required으로 실패합니다.

+0

서버가 이전 요청에 대한 응답의 일부가 아닌 데이터를 보내는 이유는 무엇입니까? – Vincent

+0

프로토콜이 잘 설계되지 않았기 때문에 2 점 통신으로 만 의미가 있습니다. – gjask

+0

가장 큰 문제는 asyncio 라이브러리에 대한 제 잘못된 이해입니다. 제 2의 호환되지 않는 문서가 제 lib의 버전에 있습니다. 내가 못했던 것은 asyncio.ensure_future 또는 asyncio.async (lib의 버전에 따라 다름)로 보류 된 상태로 설정 한 다음 이벤트 루프를 실행하여 원하는만큼 많은 작업을 생성 할 수 있다는 것입니다. – gjask

답변

0

은 함수이며, h.connect()은 코 루틴입니다. 올바른 코드는 다음과 같습니다.

class MyHandler: 
    @asyncio.coroutine 
    def connect(self): 
     self.reader, self.writer = asyncio.open_connection('localhost', 2020) 

     while True: 
      msg = yield from self.reader.readline() # Yield from since it's a coroutine 
      if msg.strip() is None: 
       yield from asyncio.sleep(1) # Also a coroutine 
       continue 
      self.handle_msg(msg) 

    @asyncio.coroutine 
    def request(self, msg): 
     self.writer.write(msg) 
     return (yield from self.reader.readline()) 

if __name__ == '__main__': 
    h = MyHandler() 
    loop = asyncio.get_event_loop() 
    loop.run_until_complete(h.connect()) 
    loop.close()