boost:asio async_receive_from同步运行

时间:2011-06-29 16:51:07

标签: c++ boost boost-asio

在下面的代码中,asynch_receive_from同步运行。在收到数据之前它不会回来。查看最后的日志表明了这一点。这可能不是那样的 起初很明显,因为有相当高的数据速率。但是当没有数据时,只有一秒钟的心跳消息,这些异步调用的返回也大约为一秒。

问题是为什么这些异步调用不会立即返回(在几个微内),并且没有读取字节?

我认为可能在运行队列中有其他项目会促进这个过程,认为如果队列中没有任何内容可以运行,io_services会将异步函数转换为同步函数,因为它还没有别的东西可以做。但是我在异步调用之前添加了2个帖子,我相信,在异步调用之前将一些内容放入运行队列中。但这似乎没有什么区别。

任何帮助将不胜感激。我是boost :: asio库的新手。

void receiver::handle_receive_from(const boost::system::error_code& error,
      size_t bytes_recvd)
{
    static char logBuf[128];    
    string dStr;
    int rVal;
    unsigned int seqNo;

    sprintf_s(logBuf, sizeof(logBuf), "BytesRead:%d", bytes_recvd);
    MyLog(logBuf);
    MyLog("1"); 
    MyLog("2");
    iosP->post(boost::bind(&receiver::postTestHandler, this));
    iosP->post(boost::bind(&receiver::postTestHandler, this));
    socket_.async_receive_from(
                boost::asio::buffer(data_, max_length), sender_endpoint_,
                boost::bind(&receiver::handle_receive_fromTwo, this,
                boost::asio::placeholders::error,
                boost::asio::placeholders::bytes_transferred));     

    MyLog("3");

}

void receiver::handle_receive_fromTwo(const boost::system::error_code& error, size_t bytes_recvd)
{
    char logBuf[128];

    sprintf_s(logBuf, sizeof(logBuf), "Two BytesRead:%d", bytes_recvd);
    MyLog(logBuf);

    MyLog("1-Two"); 
    MyLog("2-Two");
    iosP->post(boost::bind(&receiver::postTestHandler, this));
    iosP->post(boost::bind(&receiver::postTestHandler, this));
    socket_.async_receive_from(
                boost::asio::buffer(data_, max_length), sender_endpoint_,
                boost::bind(&receiver::handle_receive_from, this,
                boost::asio::placeholders::error,
                boost::asio::placeholders::bytes_transferred));         


    MyLog("3-Two");

}

void receiver::postTestHandler()
{   
    int count(0);
    MyLog("***postTestHandler entry***");
    printf("***postTestHandler entry***\n");
    printf("Exiting postTestHandler\n");
    MyLog("Exiting postTestHandler");
}

日志片段

[11:57:51.653647]BytesRead:16
[11:57:51.653660]1
[11:57:51.653662]2
[11:57:51.653692]3
[11:57:51.653697]***postTestHandler entry***
[11:57:51.654310]Exiting postTestHandler
[11:57:51.654315]***postTestHandler entry***
[11:57:51.654657]Exiting postTestHandler
[11:57:51.727494]Two BytesRead:67
[11:57:51.727503]1-Two
[11:57:51.727506]2-Two
[11:57:51.727524]3-Two
[11:57:51.727529]***postTestHandler entry***
[11:57:51.728060]Exiting postTestHandler
[11:57:51.728065]***postTestHandler entry***
[11:57:51.728407]Exiting postTestHandler
[11:57:52.438916]BytesRead:67
[11:57:52.438929]1
[11:57:52.438932]2
[11:57:52.438961]3
[11:57:52.438965]***postTestHandler entry***
[11:57:52.439568]Exiting postTestHandler
[11:57:52.439573]***postTestHandler entry***
[11:57:52.439914]Exiting postTestHandler
[11:57:52.581333]Two BytesRead:67
[11:57:52.581346]1-Two
[11:57:52.581349]2-Two
[11:57:52.581375]3-Two
[11:57:52.581381]***postTestHandler entry***
[11:57:52.582011]Exiting postTestHandler
[11:57:52.582016]***postTestHandler entry***
[11:57:52.582358]Exiting postTestHandler
[11:57:52.582364]BytesRead:67
[11:57:52.582367]1
[11:57:52.582370]2
[11:57:52.582377]3
[11:57:52.582381]***postTestHandler entry***
[11:57:52.582717]Exiting postTestHandler
[11:57:52.582722]***postTestHandler entry***
[11:57:52.583055]Exiting postTestHandler
[11:57:52.583061]Two BytesRead:67
[11:57:52.583064]1-Two
[11:57:52.583066]2-Two
[11:57:52.583077]3-Two
[11:57:52.583081]***postTestHandler entry***
[11:57:52.583418]Exiting postTestHandler
[11:57:52.583423]***postTestHandler entry***
[11:57:52.583755]Exiting postTestHandler
[11:57:52.616525]BytesRead:67
[11:57:52.616531]1
[11:57:52.616533]2
[11:57:52.616549]3
[11:57:52.616553]***postTestHandler entry***
[11:57:52.617015]Exiting postTestHandler
[11:57:52.617020]***postTestHandler entry***
[11:57:52.617362]Exiting postTestHandler

1 个答案:

答案 0 :(得分:2)

不确定您是否仍然遇到此问题,但在调用io_service.run()后它会阻塞,因为它将无限期地查找已收到的数据包。如果你想检查回调,但是如果没有阻止则不阻止,那么使用io_service.poll()。如果你希望它只执行一个回调(如果有一个或多个请求),那么使用io_service.poll_one()。

不确定这是不是你的问题,或者你是否还有这个问题(我知道这个问题很老),但祝你好运!

编辑(回复您的评论):

如果你使用io_service.run(),那么该线程将永远致力于处理asio回调。但是,如果您使用io_service.poll(),那么您可以在需要时处理回调,然后在此期间执行其他操作。 io_service.poll()绝不比io_service.run()快,它只是让你能够随时处理回调,而不是总是无限期地处理回调。

您可能想象io_service.run()的实现方式如下:

void IOService::run()
{
    while (true)
    {
        poll();
    }
}

请注意,它没有像这样实现。但这可能会清除运行和民意调查的概念。