2017-10-31 4 views
1

ASIO 독립형 라이브러리 (Boost ASIO가 아님)를 사용하려고합니다. 클라이언트를 설정하여 특정 포트의 서버에 연결하려고합니다.ASIO가 비동기식 해결에서 직접 tcp 엔드 포인트 받기

porthopper 예에서 반복기를 다루지 않고도 끝점을 얻을 수 있다는 것을 알았습니다.

asio::io_service io_service; 

// Determine the location of the server. 
tcp::resolver resolver(io_service); 
tcp::resolver::query query(host_name, port); 
tcp::endpoint remote_endpoint = *resolver.resolve(query); 

해결 방법 async_resolve() 멤버 함수를 사용하여 쿼리를 해결하려고합니다.

asio::io_service IOService; 
asio::ip::tcp::resolver resolver(IOService); 
asio::ip::tcp::resolver::query query(ADDRESS, PORT); 
resolver.async_resolve(query, 
      [this](const tcp::endpoint srvEndpoint, std::error_code error) 
      { 
       IOService->post(
        [this, error, srvEndpoint] 
        { 
         handle_resolve_handler(error, srvEndpoint); 
        }); 
      }); 

porthopper의 예와 같이 한 일을하지만, 비동기 적으로 수행 할 수있는 방법이 있나요 :

이 내가 현재 가지고있는 코드는? 매우 반복자와

답변

1

아,하지만

tcp::endpoint remote_endpoint = *resolver.resolve(query); 

거래! 그것을 참조를 위해 사용합니다. 귀여운 별에 주목해라. pointer indirection 연산자입니다. 전화에 관해서는

:

resolver.async_resolve(query, 
      [this](const tcp::endpoint srvEndpoint, std::error_code error) 
      { 
       IOService->post(
        [this, error, srvEndpoint] 
        { 
         handle_resolve_handler(error, srvEndpoint); 
        }); 
      }); 

완료 핸들러 요구 사항을 충족하지 않습니다. Live On Coliru :

main.cpp:12:14: required from here 
/usr/local/include/boost/asio/ip/basic_resolver.hpp:163:5: error: static assertion failed: ResolveHandler type requirements not met 
    BOOST_ASIO_RESOLVE_HANDLER_CHECK(
    ^
/usr/local/include/boost/asio/ip/basic_resolver.hpp:163:5: error: no match for call to '(Demo::doResolve()::<lambda(boost::asio::ip::tcp::endpoint, boost::system::error_code)>) (const boost::system::error_code&, const boost::asio::ip::basic_resolver_iterator<boost::asio::ip::tcp>&)' 
    BOOST_ASIO_RESOLVE_HANDLER_CHECK(

The docs say : 사실, 부스트 Asio²으로 컴파일하려고하면 오류가의 슬루 제공

enter image description here

소호를 보라, 다시 반복자있다! 이것은 결코 사고가 아닙니다. Live On Coliru

#include <boost/asio.hpp> 
#include <iostream> 

namespace asio = boost::asio; 
using boost::system::error_code; 
using asio::ip::tcp; 

struct Demo { 
    Demo(asio::io_service& svc) : _svc(svc) {} 
    void doResolve() { 
     resolver.async_resolve(query, [this](error_code error, tcp::resolver::iterator it) { 
       tcp::endpoint ep = error? tcp::endpoint{} : *it; 
       _svc.post([this, error, ep] { handle_resolve_handler(error, ep); }); 
      }); 
    } 

    private: 
    asio::io_service& _svc; 
    tcp::resolver resolver  {_svc}; 
    tcp::resolver::query query {"www.google.com", "https"}; 

    void handle_resolve_handler(error_code ec, tcp::endpoint srvEndpoint) { 
     std::cout << "handle_resolve_handler: " << ec.message() << " " << srvEndpoint << "\n"; 
    } 
}; 

int main() { 
    asio::io_service svc; 
    Demo x(svc); 
    x.doResolve(); 

    svc.run(); 
} 

Prints³ : 라이브러리의 설계는 비동기 호출이 항상 선택

interface.¹가 함께 않은 인터페이스에 관계없이 동일한 데이터를 반환하도록이다

handle_resolve_handler: Success 216.58.213.196:443 

¹ cf. 코 루틴을 사용하여 차이 (yield 또는 yield[ec]), asio::use_future 등 : How to set error_code to asio::yield_context

² 기본적으로 네트워크 액세스 시스템에서 s/boost::system::error_code/std::error_code/

³