首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Boost::asio和async_read

Boost::asio和async_read
EN

Stack Overflow用户
提问于 2011-08-08 23:31:06
回答 1查看 3.2K关注 0票数 1

我正在尝试使用Boost::asio和async_read在使用串口的协议中实现超时。

我已经使用同步读取做了一个测试实现,它只需查找,但我的超时实现不起作用。

代码语言:javascript
复制
void set_result( boost::optional<boost::system::error_code> * a, boost::system::error_code b ) {
    a->reset( b );
}

void receive(boost::asio::io_service & io, boost::asio::serial_port & cctalk_port, boost::asio::streambuf & result){
#if 1
    // Non-working implementation with timeout
    boost::optional<boost::system::error_code> timer_result;
    boost::optional<boost::system::error_code> read_result;

    boost::asio::deadline_timer timer( io );
    LOG(INFO) << "Timer at 5000ms starts here";
    timer.expires_from_now( boost::posix_time::milliseconds(5000) ); // allow up to 50ms of timeout for every char
    timer.async_wait( boost::bind(&set_result, &timer_result, _1) );

    LOG(INFO) << "Async read starts here (result.size() == " << result.size() << ")";
    boost::asio::async_read(
            cctalk_port,
            result,
            boost::asio::transfer_at_least(1),
            boost::bind( &set_result, &read_result, _1 ));
    boost::system::error_code ec;

    while(1) {
        io.poll_one(ec);

        if( ec != 0 || read_result != 0 || timer_result != 0)
            LOG(INFO) << "Error code: " << ec << " read_result: " << read_result << " timer_result: " << timer_result;

        if ( read_result ) {
            timer.cancel();
            LOG(INFO) << "Result ready (" << result.size() << ")";
            return;

        } else if ( timer_result ) {
            LOG(INFO) << "Timeout";
            throw runtime_error("timeout");
        }
    }

    LOG(INFO) << "Not suppose to happen";

#else
    // Working implementation without timeout
    boost::asio::read(cctalk_port, result, boost::asio::transfer_at_least(1));
#endif
}

void receive(boost::asio::io_service & io, boost::asio::serial_port & cctalk_port, size_t size, boost::asio::streambuf & result){
    LOG(INFO) << "Fetch at least " << size << " has allready: " << result.size();
    while( result.size() < size ) {
        receive(io, cctalk_port, result);
        LOG(INFO) << "Buffer size: " << result.size() << "/" << size;
    }
}

当我运行这段代码时,我得到了以下输出:

代码语言:javascript
复制
I0808 17:25:40.809615  3682 ccTalkScan.cxx:137] Fetch at least 5 has allready: 0
I0808 17:25:40.809672  3682 ccTalkScan.cxx:99] Timer at 5000ms starts here
I0808 17:25:40.809686  3682 ccTalkScan.cxx:103] Async read starts here (result.size() == 0)
I0808 17:25:40.809731  3682 ccTalkScan.cxx:115] Error code: system:0 read_result: 1 timer_result: 0
I0808 17:25:40.809738  3682 ccTalkScan.cxx:119] Result ready (12)
I0808 17:25:40.809742  3682 ccTalkScan.cxx:140] Buffer size: 12/5
I0808 17:25:40.809778  3682 ccTalkScan.cxx:137] Fetch at least 5 has allready: 7
I0808 17:25:40.809783  3682 ccTalkScan.cxx:137] Fetch at least 9 has allready: 7
I0808 17:25:40.809788  3682 ccTalkScan.cxx:99] Timer at 5000ms starts here
I0808 17:25:40.809797  3682 ccTalkScan.cxx:103] Async read starts here (result.size() == 7)
I0808 17:25:40.809808  3682 ccTalkScan.cxx:115] Error code: system:0 read_result: 0 timer_result: 1
I0808 17:25:40.809811  3682 ccTalkScan.cxx:123] Timeout

从输出中可以看出,设置的计时器必须快于5000ms,在这种情况下小于1ms。

此外,通过查看我收到的实际字节,我似乎遗漏了第一个字节。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-08-08 23:56:44

嗯..。这里的问题很微妙,基本上是当您取消前一个计时器时-另一个事件在io_service (调用负责该计时器的处理程序)上触发,以指示它已经被取消(使用适当的error_code)。因为您只调用poll_one,所以读取就可以了,所以您处理读取,然后取消计时器(它在io_service上设置后续事件-但对于这次运行,它不会被调用)-然后当第二次调用您的receive()方法时,您调用poll_one -此事件被触发(因为您不检查set_result方法中的错误条件),可选的状态是良好的(它包含一个错误),您将其视为超时...

跟上?

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6984571

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档