boost :: asio :: async_read循环无限,接收数据为零字节

时间:2017-07-27 18:55:06

标签: c++ boost boost-asio asio

我正在尝试编写基于IO_Service的异步TCP客户端,其中Async_write工作正常,但async_read在无限循环中运行。在我的审判纠正问题期间,我发现在所有其他情况下,async_read只是停止接收数据,它直到我停止服务器才收到任何内容。下面是我在发布查询之前尝试的代码和链接。

我尝试的建议是exactly as mine23 and,但在所有情况下,我的async_read处理程序都没有读取任何内容。在一个且仅有一种情况下,当我在其他情况下将缓冲区设置为boost::asio::mutable_buffer bytes;时,它会启动无限循环我已尝试boost::array<char, 512> bytes;boost::asio::streambuf bytes;char bytes[512];,其中不会引发async_read处理程序

在完成所有这些解决方案后,我现在感到困惑:这可能是缓冲区的问题吗?在传递阅读之前是否需要初始化它 ?

请指导。

ScalableSocket::ScalableSocket()
{
    //ctor

    using namespace boost::asio;
    service = boost::make_shared<io_service>();
    work =    boost::make_shared<io_service::work>(*service );
    strand  = boost::make_shared<io_service::strand>( *service );
    worker_threads = boost::make_shared<boost::thread_group>();



        worker_threads->create_thread(boost::bind(&ScalableSocket::WorkerThread,this));


    resolver = boost::make_shared<boost::asio::ip::tcp::resolver> (*service);

    tcp_socket= boost::make_shared<boost::asio::ip::tcp::socket> (*service);

    boost::asio::ip::tcp::resolver::query q(boost::asio::ip::tcp::v4(),"192.168.100.96","9602");

    boost::asio::ip::tcp::resolver::iterator it = resolver->resolve(q);

    boost::asio::async_connect(*tcp_socket,it,boost::bind(&ScalableSocket::connect_handler,this,boost::asio::placeholders::error));

    tcp_socket->set_option(boost::asio::ip::tcp::no_delay(true) );

}

ScalableSocket::~ScalableSocket()
{
    //dtor

}

void ScalableSocket::PublishPost()
{
    strand->post(boost::bind(&ScalableSocket::OnSend,this));
}


void ScalableSocket::OnSend()
{


    boost::array<char, 6> a = { 'a', 'b', 'c', 'd', 'e' };

    boost::asio::async_write(*tcp_socket,boost::asio::buffer(a),
                                    boost::bind(&ScalableSocket::write_handler, this, boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));



}

void ScalableSocket::WorkerThread()
{
    while( true )
    {
        try
        {
            boost::system::error_code ec;
            service->run( ec );
            if( ec )
            {
                ///LOGE(ec);
            }
            break;
        }
        catch( std::exception & ex )
        {
            ///LOGE(ex.what());
        }
    }
}

void ScalableSocket::connect_handler(const boost::system::error_code &ec)
{
    if (!ec)
    {

    PublishPost();




/* boost::asio::async_read(*tcp_socket,
                                boost::asio::buffer(bytes),
                                boost::bind(&ScalableSocket::read_handler, this,
                                            boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
*/

        ///https://stackoverflow.com/questions/4527443/problems-using-boostasioasync-read

        boost::shared_ptr<boost::array<char, 512>> buf(new boost::array<char, 512>);


        boost::asio::async_read(*tcp_socket,boost::asio::buffer(*buf),
                                boost::bind(&ScalableSocket::read_handler, this,buf,
                                boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));

    }
    else
    {
        cout<<" Some error connecting to Exchange  "<< ec.message()<<endl;

    }

}


void ScalableSocket::OnTimer(const boost::system::error_code &ec)
{
    if(!ec)
    {
        printf("\n\n Heartbeat event raised sending KeepAlive to exchange \n\n");
        PublishPost();
        HeartBeatTimer->async_wait(boost::bind(&ScalableSocket::OnTimer,this, boost::asio::placeholders::error));
    }
}

void ScalableSocket::recvData()
{
    boost::system::error_code error;
    boost::array<char, 1024> buf;

    //for(;;)
    {
        size_t len = tcp_socket->read_some(boost::asio::buffer(buf), error);

        cout<<"\n Recv data size is "<<len;

    }
}

void ScalableSocket::read_handler(boost::shared_ptr<boost::array<char, 512>> buf,const boost::system::error_code &ec,std::size_t bytes_transferred)
{


    if (!ec )//&& bytes_transferred > 0)
    {

        ///recvData(); /// If i enable this code during infinite loop it start getting data that means socket has no issue

        cout << " Data size recieved "<< bytes_transferred<<endl;




            boost::asio::async_read(*tcp_socket,boost::asio::buffer(*buf),
                                boost::bind(&ScalableSocket::read_handler, this,buf,
                                boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
    }
    else
    {
        /// Some issue with socket publish error , inform user and reconnect
        cout<<" Some error reading data from Exchange  "<< ec.message()<<endl;

    }
}

void ScalableSocket::write_handler(const boost::system::error_code& error,std::size_t bytes_transferred)
{
    if(!error)
    {
        /// data Sent successfully
        cout<< " Data sent size "<< bytes_transferred<<endl;

    }
    else
    {
        cout<<" Some error sending data to Exchange  "<< error.message()<<endl;
    }

}

1 个答案:

答案 0 :(得分:1)

asnyc_read不会&#34;返回&#34; /调用处理程序,直到给定的缓冲区完全填满。

读取一些字节后,

asnyc_read_some将返回。这可能是您正在寻找的功能。

请记住使用asnyc_read_some正确处理收到的数据。如果发送512个字节,它可能会在几次读取时到达,具体取决于机器。