boost website에 주어진 HTTP 서버의 예제를 기반으로 HTTP 클라이언트를 빌드하고 있습니다. 이제이 코드와 다른 점은 서버 생성자를 사용하여 비동기 작업을 시작한다는 것입니다. 이것은 서버가 항상 듣기로되어 있기 때문에 의미가 있습니다. 내 클라이언트에서는 다른 한편으로는 먼저 객체를 구성한 다음 send()
함수를 끝점에 연결하여 시작하고 나중에 요청을 보내고 마지막으로 응답을 수신하려고합니다. 이것은 너무 의미가 있습니다, 안 그래요?boost :: asio를 사용할 때의 참조 문제 (아마도)
개체 (클라이언트)를 만들 때 서버 예제 (winmain.cpp)와 같은 방식으로 작업을 수행합니다. 그것은 다음과 같습니다
client c("www.boost.org);
c.start(); // starts the io_service in a thread
c.send(msg_);
코드의 관련 부분은 다음과 같습니다
void enabler::send(common::geomessage& msg_)
{
new_connection_.reset(new connection(io_service_,
connection_manager_,
message_manager_, msg_
));
boost::asio::ip::tcp::resolver resolver(io_service_);
boost::asio::ip::tcp::resolver::query query(host_address, "http");
resolver.async_resolve(query, boost::bind(
&enabler::handle_resolve,
boost::ref(*this),
boost::asio::placeholders::error,
boost::asio::placeholders::iterator
));
}
void enabler::run()
{
io_service_.run();
}
이의 문제는 프로그램이 여기 어딘가에 붙어 도착한다는 것입니다. 마지막으로 인쇄되는 것은 "해결 호스트"입니다. 그 후 프로그램이 종료됩니다. io_service
이 모든 비동기 작업이 콜백으로 반환 될 때까지 차단해야하기 때문에 왜 그런지 모르겠습니다. 그러나 함수의 호출 순서를 변경하면 작동합니다. async_resolve()
에 대한 호출 직후 run()
으로 전화를 걸고 내 주 프로그램에서 start()
을 호출하지 않으면 작동합니다!
이 시나리오에서는 io_service
블록을 사용해야하며 서버에서 응답을받을 수 있습니다.
async_resolve()
과 같은 클래스 안에서 run()
을 호출한다는 점에서 뭔가가 있습니다. 이것이 사실일까요? 내가 run()
라고 부를 때 주 프로그램에서 참고할 필요가 있다고 생각합니까?
저는 io_service::work
을 사용하는 데 어려움을 겪었지만 프로그램이 멈추었 고 예와 비슷한 문제가 발생했습니다. 그래서 그것은 정말로 도움이되지 않습니다.
그렇다면이 권리를 얻기 위해 무엇을 할 수 있습니까? 앞서 말했듯이 클라이언트 객체를 만들고 클라이언트 클래스 내의 별도 스레드에서 항상 실행중인 io_service
을 가질 수 있어야합니다. 둘째, 서버에 요청을 보내는 기능이있는 send()
입니다.
감사합니다. async_resolve() 바로 뒤에 send() 함수에서 run()을 호출 할 수 있습니다. 그러나 문제는 run()이 이미 호출 된 경우 다시 호출하는 것이 잘못된 것입니다.현재 run()이 끝나기 전에 요청을 보낼 수 있도록 send()를 사용하고 싶습니다. io_service가 끝났는지를 결정할 수있는 방법이 있는가? 그리고 실행을 다시 호출해도 안전한지 판단 할 수 있는가? 그게 효과가 있다면 좋을 것입니다. 그 이유는 if 문에서 이것을 체크 할 수 있기 때문입니다. –
당신이 실제로 사용할 수있는 것처럼 들리는 것은 run()이 무기한으로 가게하는 것입니다. 그래서 그것에 대해 걱정할 필요가 없습니까? asio 문서에는 [해당 섹션 만 있습니다] (http://www.boost.org/doc/libs/1_46_1/doc/html/boost_asio/reference/io_service.html#boost_asio.reference.io_service.stopping_the_io_service_from_running_out_of_work). –
예! 그게 정확히 내가 원하는 걸! 하지만 이미 참조한 페이지를 읽고 ioservice :: work로 작업 할 수 없습니다. 클라이언트 클래스의 private 변수로 정의 된 io_service가 있습니다. 내 run() 함수에서이 시도했다 : boost :: asio :: io_service :: work work (io_service_); io_service_.run(); 그런 다음 전체 작업을 중지하려면 io_service_.stop();을 호출해야합니다. 그 맞습니까? 왜냐하면 난 그저 일을 할 수 있기 때문이야. –