C++ 向ASIO中的UDP调用接收应用超时

C++ 向ASIO中的UDP调用接收应用超时,c++,c++11,networking,asio,C++,C++11,Networking,Asio,我有下面的ASIO代码,它同步读取UDP数据包。问题是,如果给定大小的数据包在给定的时间范围(30秒)内没有到达,我希望receive_from函数返回某种类型的错误以指定超时 for (;;) { boost::array<char, 1000> recv_buf; udp::endpoint remote_endpoint; asio::error_code error; socket.receive_from(asio::buffer(recv_buf),

我有下面的ASIO代码,它同步读取UDP数据包。问题是,如果给定大小的数据包在给定的时间范围(30秒)内没有到达,我希望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);
}
(;;)的

{
boost::数组recv_buf;
udp::端点远程_端点;
asio::错误\代码错误;

socket.receive_from(asio::buffer(recv_buf))/据我所知,这是不可能的。通过运行同步
receive_from
,您已经通过系统调用
recvmsg
from
\include
阻止了代码执行

随着可移植性的发展,我无法为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_服务中运行它,据我所知,这是不可能的。通过运行同步
receive_from
,您已经通过
\include
的系统调用
recvmsg
阻止了代码执行

随着可移植性的发展,我无法为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_服务中运行它

肯定有与SO_RCVTIMEO?@EJP相当的东西,我希望会有,但文档中没有提到。您可以使用
select()来合成它
,但是你在asio中是这样做的。肯定有相当于SO_RCVTIMEO?@EJP的东西,我希望会有,但是文档化中没有提到。你可以用
select()
合成它,但是你在asio中是这样做的。