Boost :: Asio - 将套接字传递给第二类

时间:2016-04-19 13:01:27

标签: c++ boost-asio

我目前正在尝试使用以下应用程序:

  1. 等待传入的客户端连接。
  2. 启动异步。计时器在另一个班级。
  3. 当计时器反复运行时,请执行其他操作,例如async_readasync_write
  4. 当前源代码

    #define BOOST_ASIO_ENABLE_HANDLER_TRACKING
    
    #include <WinSock2.h>
    #include <Mswsock.h>
    #include <boost/asio.hpp>
    #include <boost/bind.hpp>
    #include "TimerClass.hpp"
    
    using namespace boost::asio;
    using namespace boost::asio::ip;
    
    TimerClass *timerClass;
    
    void acceptHandler(const boost::system::error_code &errorCode, tcp::socket *socket) {
        timerClass = new TimerClass(socket);
        timerClass->startTimer();
        while(true) {
            // Do other suff such as async_write, ...
        }
    }
    
    int main(int argc, char** argv) {
        io_service ioService;
        tcp::socket socket(ioService);
        tcp::acceptor acceptor{ ioService, tcp::endpoint{ tcp::v4(), 12345 } };
        acceptor.listen();
        acceptor.async_accept(socket, boost::bind(acceptHandler, _1, &socket));
        ioService.run();
        return EXIT_SUCCESS;
    }
    

    TimerClass.hpp

    #include <boost/asio.hpp>
    #include <boost/date_time/posix_time/posix_time.hpp>
    
    using namespace boost::asio;
    using namespace boost::posix_time;
    
    class TimerClass {
    public:
        TimerClass(ip::tcp::socket *socket);
        void startTimer();
        void timerHandler(const boost::system::error_code& errorCode);
        deadline_timer timer;
    };
    

    TimerClass.cpp

    #include <boost/bind.hpp>
    #include "TimerClass.hpp"
    
    TimerClass::TimerClass(ip::tcp::socket *socket) : timer(socket->get_io_service(), boost::posix_time::seconds(1)) {}
    
    void TimerClass::startTimer() {
        timer.async_wait(boost::bind(&TimerClass::timerHandler, this, boost::asio::placeholders::error));
    }
    
    void TimerClass::timerHandler(const boost::system::error_code& errorCode) {
        timer.expires_at(timer.expires_at() + boost::posix_time::seconds(1));
        timer.async_wait(boost::bind(&TimerClass::timerHandler, this, boost::asio::placeholders::error));
    }
    

    处理程序跟踪输出

    @asio|1461070492.111630|0*1|socket@000000000021FBD0.async_accept
    @asio|1461070498.527997|>1|ec=system:0
    

    问题

    1. 为什么甚至不会在async_wait中拨打startTimer?调试显示startTimer被调用,但我在Handler Tracking输出中找不到任何内容。那是为什么?
    2. 我是否正确地将套接字传递给TimerClass?
    3. 如果在acceptHandler中没有无限while(true)循环,则acceptHandler返回,但应用程序在io_service正确返回之前崩溃。怎么样?

1 个答案:

答案 0 :(得分:2)

我编译了你的代码,它适用于我(使用boost版本1.54)。

使用您的代码我得到以下输出:

<?php

exec('cmd /k c:/wamp/www/javac Main.java 2>&1', $outputAndErrors, $return_value);
for($i=0 ; $i<sizeof($outputAndErrors) ; $i++)
{
    $output1=htmlspecialchars($outputAndErrors[$i],ENT_QUOTES);
    echo "$output1";    
    $flag=1;
}
if(!$flag)
{
    exec('cmd /k c:/wamp/www/java Main.java < input.txt > output.txt', $outputAndErrors, $return_value);
    //want to give timeout but if exec goes to infinite loop than below statement will not executed
}

?>

为了让它正常运行,我必须删除@asio|1461081908.437388|0*1|socket@003BFE2C.async_accept @asio|1461081983.220840|>1|ec=system:0 @asio|1461081983.221817|1*2|deadline_timer@001C1318.async_wait 上的while(true),获取以下输出(在处理程序中添加了acceptHandler):

std::cout

我实际上只使用标题@asio|1461083707.104424|0*1|socket@0030FB6C.async_accept @asio|1461083709.061824|>1|ec=system:0 @asio|1461083709.062803|1*2|deadline_timer@00641318.async_wait @asio|1461083709.062803|<28158494073611763| @asio|1461083710.064992|>2|ec=system:0 @asio|1461083710.064992|2|deadline_timer@00641318.cancel @asio|1461083710.064992|2*3|deadline_timer@00641318.async_wait TimerHandler executed... @asio|1461083710.065971|<28169626628843099| @asio|1461083711.065223|>3|ec=system:0 @asio|1461083711.065223|3|deadline_timer@00641318.cancel @asio|1461083711.065223|3*4|deadline_timer@00641318.async_wait TimerHandler executed... 进行了此测试(直接在其中定义方法 - 我很懒) - 它就像一个魅力,问题似乎是在使用TimerClass.hpp时文件,这就是为什么我问你是否使用包含警卫(虽然已经过测试但不是问题)。

您应该考虑更改您的设计方法,即不要在处理程序中使用阻塞循环,只需在需要时调用另一个异步操作(如.cppasync_read)。

查看this question以及相应的已接受答案,了解一个不错的服务器实现方法。或者尝试根据您的需要调整部分boost examples

根据您在相应标头和实现文件中将声明与定义分开时获得的分段错误,您可能需要检查this other question