私はすでにこれに長い間取り組んでいますが、成功していません。
あなたの主な機能が次のようなものだと想像してみてください。
bool running = true;
int i = 0;
//waitHandler();
while(running)
i++;
次に、タイマーを追加して呼び出します。タイマーは、有効期限が切れたときに実行をfalseに設定します。
void waitHandler(){
boost::asio::io_service timerService;
//create and bind the timer
boost::asio::deadline_timer timer(timerService,
boost::posix_time::milliseconds(2000));
timer.wait();
running = true;
cout<<"WaitHandler triggered"<<endl;
}
もちろん、タイマーがメインスレッドをブロックするため、これは機能しません(uが上記のコメントのコメントを解除した場合)。main関数をブロックせずにこの機能を使用したい場合はどうすればよいですか。
編集:
//transfer some error message
void set_result(boost::system::error_code* a, boost::system::error_code b,deadline_timer &timer)
{
a->assign(b.value(),b.category());
}
template<class SOCKET>
void read_with_timeout(SOCKET & sock, unsigned int delay,
const asio::mutable_buffers_1& buffers)
{
//create error messages
boost::system::error_code timer_result;
boost::system::error_code read_result;
//initialize timer
deadline_timer timer(sock.get_io_service());
timer.expires_from_now(boost::posix_time::milliseconds(delay));
timer.async_wait(boost::bind(set_result, &timer_result, _1,boost::ref(timer)));
//initialize receive mechanism
sock.async_receive(buffers, boost::bind(set_result, &read_result, _1,boost::ref(timer)));
sock.get_io_service().reset();
//should run for one handler
while (sock.get_io_service().run_one())
{
if (read_result.value()==0){ //zero stands for, that the message was received properly.
timer.cancel();
//cout<<"Message received: => Timer cancelled => RETURN!"<<endl;
return;
}
if(timer.expires_from_now().total_milliseconds() <=0){
sock.cancel();
//cout<<"Timeout => Socket cancelled => RETURN!"<<endl;
return;
}
}
}
言ったように、これはほとんど望ましい振る舞いを示していますが、それにはいくつかの質問があります:
- なぜ、を使用しても
run_one
、タイマーのハンドラーと受信のハンドラーの両方を起動できるのはなぜですか - 0バイトを受信したときに、受信も発生するのはなぜですか。私にとっては、何も受信されておらず、関数が待機することになっているように聞こえますか?
- これは正しい方法ですか?私が受信またはタイムアウトしたいと言ったように。(pingのように)
async_receive
実際、パケットはWiresharkに表示されたときに間違った順序で受信されます。これは、着信メッセージを実際に待機するのではなく、関数呼び出しの前にバッファにあるものを取得するだけであると関係があると思います。
何をすべきか?