2017-04-26 7 views
1

私は以下のASIOコードを持ち、同期してUDPパケットを読み取ります。問題は、与えられたサイズのデータ​​パケットが与えられた時間フレーム(30秒)に到着していない場合です。私はrecieve_from関数が何らかの種類のエラーで特定のタイムアウトに戻ることを望みます。ASIOのUDPコールreceive_fromにタイムアウトを適用する

for (;;) 
{ 
    boost::array<char, 1000> recv_buf; 
    udp::endpoint remote_endpoint; 
    asio::error_code error; 

    socket.receive_from(asio::buffer(recv_buf), // <-- require timeout 
     remote_endpoint, 0, error); 

    if (error && error != asio::error::message_size) 
    throw asio::system_error(error); 

    std::string message = make_daytime_string(); 

    asio::error_code ignored_error; 
    socket.send_to(asio::buffer(message), 
     remote_endpoint, 0, ignored_error); 
} 

UDP指向コール以外のドキュメントでは、タイムアウトメカニズムがサポートされています。

ASIOでの同期UDPコールでタイムアウトする正しい方法(可能であれば移植可能)は何ですか?

+0

確かにSO_RCVTIMEOに相当するものがありますか? – EJP

+1

@EJP私はそこにいると思っていたが、何も文書には触れていない –

+0

すばらしかった。 'select()'で合成することはできますが、asioで行います。 – EJP

答えて

0

私が知る限り、これは不可能です。同期receive_fromを実行すると、コード実行がブロック・recvmsg#include <sys/socket.h>からブロックされています。

ポータビリティが行くように、私はWindowsのために話すことはできませんが、Linux/BSDのC-風味のソリューションは、次のようになります。私は、完全な非同期および実行を行く推薦する、これは全く不可能な場合

void SignalHandler(int signal) { 
    // do what you need to do, possibly informing about timeout and calling exit() 
} 

... 
struct sigaction signal_action; 
signal_action.sa_flags = 0; 
sigemptyset(&signal_action.sa_mask); 
signal_action.sa_handler = SignalHandler; 
if (sigaction(SIGALRM, &signal_action, NULL) == -1) { 
    // handle error 
} 
... 
int timeout_in_seconds = 5; 
alarm(timeout_in_seconds); 
... 
socket.receive_from(asio::buffer(recv_buf), remote_endpoint, 0, error); 
... 
alarm(0); 

をそれはboost::asio::io_serviceです。

関連する問題