2017-07-27 78 views
0

我想寫基於IO_Service的異步TCP客戶端,其中Async_write工作正常,但async_read在無限循環中運行。在我嘗試糾正這個問題的過程中,我發現在所有其他情況下,async_read只是停止接收數據,直到我停止服務器時纔會收到任何內容。以下是發佈我的查詢之前我嘗試的代碼和鏈接。boost :: asio :: async_read循環無限與零字節的接收數據

我試過的建議是exactly as mine23and但在所有的情況下,我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; 
    } 

} 
+0

但你知道'asnyc_read'將不會「返回」/調用處理程序,直到給定的緩衝區完全滿了,對嗎? – Blacktempel

+0

我使用這種512種緩衝,一旦我沒有收到任何東西使用boost streambuffer或可變緩衝區,然後我嘗試使用512的東西,遵循堆棧本身的一些解決方案 –

+0

一些標點符號將有助於識別您的評論。嘗試發送512字節以上的數據,看看您是否收到了正確的數據。 – Blacktempel

回答

0

asnyc_read不會「迴歸」 /調用處理程序,直到給定的緩衝區完全充滿。

asnyc_read_some將在讀取一些字節後返回。這可能是你正在尋找的功能。

請記住用asnyc_read_some正確處理收到的數據。如果發送512字節,則可能會以幾次讀取爲準,具體取決於機器。

相關問題