2014-01-22 42 views
0

我努力的TCP-Server,該服務器讀取數據,處理它們並把他們送回。之後,它將等待新的數據。我的問題是,服務器第一次發送數據時工作正常。第二次,程序停留在run_one() -loop。加速TCP async_receive_some不讀第二次

size_t m_lengthReceive; 
io_service m_ioService; 
std::vector<unsigned char> m_vectorBuffer; 
unsigned char m_bufferReceive[128]; 


void SyncServer::initialize(){  
     m_acceptor = shared_ptr<tcp::acceptor>(
       new tcp::acceptor(m_ioService, 
         tcp::endpoint(tcp::v4(), m_port))); 

     m_acceptor->set_option(tcp::acceptor::reuse_address(true)); 
     m_sock = shared_ptr<tcp::socket>(new tcp::socket(m_ioService)); 

     m_acceptor->accept(*m_sock, m_ec); 
} 

void SyncServer::tcpReceiveVector(){ 
     boost::system::error_code ec; 
     m_sock->async_read_some(buffer(m_bufferReceive), 
       boost::bind(&SyncServer::tcpReceiveHandler, this, 
         boost::asio::placeholders::error, 
         boost::asio::placeholders::bytes_transferred)); 
     do{ 
      m_ioService.run_one(); 
     }while(m_lengthReceive == 0); 
} 


void SyncServer::tcpReceiveHandler(const boost::system::error_code& ec, 
     size_t size){ 
    if(size > 0 && !ec){ 
     m_sock->cancel(); 
     m_lengthReceive = size; 
     m_vectorBuffer.resize(m_lengthReceive); 
     int i = 0; 
     for(std::vector<unsigned char>::iterator it = m_vectorBuffer.begin(); 
       it != m_vectorBuffer.end(); ++it){ 
      *it = m_bufferReceive[i]; 
      ++i; 
     } 
    }else{ 
     m_lengthReceive = 0; 
     m_sock->async_read_some(buffer(m_bufferReceive), 
       boost::bind(&SyncServer::tcpReceiveHandler, this, 
         boost::asio::placeholders::error, 
         boost::asio::placeholders::bytes_transferred)); 
    } 
} 

std::vector<unsigned char> SyncServer::getVectorBuffer(){ 
    return m_vectorBuffer; 
} 

void SyncServer::openConnection(){ 
    if(!m_sock->is_open()) 
     m_sock->open(tcp::v4()); 
    m_lengthReceive = 0; 
} 

void SyncServer::closeConnection(){ 
    m_sock->close(); 

} 

main(){ 
    m_tcpServer = shared_ptr<SyncServer>(new SyncServer(m_tcpPort)); 
    m_tcpServer->initialize(); 
    while(1){ 
     m_tcpServer->openConnection(); 
     m_tcpServer->tcpReceiveVector(); 
     vector = m_tcpServer->getVectorBuffer(); 

     //do something with vector 

     m_tcpServer->tcpSend(vector); //this works fine 
     m_tcpServer->closeConnection(); 
    } 
} 

更新的代碼:(?)

void SyncServer::tcpReceiveHandler(const boost::system::error_code& ec, 
     size_t size){ 
    if(ec){ 
     std::cout<< ec << std::endl; 
    }else{ 
     if(size > 0){ 
      m_sock->cancel(); 
      m_lengthReceive = size; 
      m_vectorBuffer.resize(m_lengthReceive); 
      int i = 0; 
      for(std::vector<unsigned char>::iterator it = m_vectorBuffer.begin(); 
        it != m_vectorBuffer.end(); ++it){ 
       *it = m_bufferReceive[i]; 
       ++i; 
      } 
     }else{ 
      m_lengthReceive = 0; 
      m_sock->async_read_some(buffer(m_bufferReceive), 
        boost::bind(&SyncServer::tcpReceiveHandler, this, 
         boost::asio::placeholders::error, 
         boost::asio::placeholders::bytes_transferred)); 
     } 
    } 
} 

回答

1

除了倪什麼米回答,你也做了古典阿西奧錯誤。這裏記載:http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/reference/io_service/run_one/overload1.html 「的後續調用運行(),run_one(),輪詢()或poll_one()將立即返回,除非有事先調用reset()方法。」

後您.run_one你需要調用m_ioservice.reset()或者它永遠不會做任何重新運行。它只是返回而不是調用任何異步操作,因此m_lengthReceive在第一次後不會改變。

do{ 
     m_ioService.run_one(); 
     m_ioService.reset(); 
    }while(m_lengthReceive == 0); 

這是人的原因通常不使用run_one()run(),最後一個的處理程序中啓動一個新的異步操作。在這種情況下,run()不會返回,並且不需要reset()

+0

解決了第一個問題。現在我得到一個錯誤107'not_connected'。現在我會試着找出問題所在。謝謝。 – cxd

+0

在第一個成功完成後,您仍然沒有開始新的'async_receive()',據我所知。所以一旦你收到了一些東西,你就可以處理它,把'm_lengthReceive'設置爲0而不是'run_one()'循環。然後你發送一些東西並關閉連接,而不需要客戶給你發送任何東西。基本上,如果你想多次接收,你需要在處理程序的'if(size> 0)'路徑中有'async_receive()',而不僅僅是'else'。 – DeVadder

+0

但我在我的主體中有一段時間(1)' - 圈,我每次都開始新的接收。這不會有幾乎相同的效果? – cxd

2

在你的接收處理程序,你只會引發另一次讀,如果有一個問題

void SyncServer::tcpReceiveHandler(const boost::system::error_code& ec, 
     size_t size){ 
    if(size > 0 && !ec){ 
     m_sock->cancel(); 
     m_lengthReceive = size; 
     m_vectorBuffer.resize(m_lengthReceive); 
     int i = 0; 
     for(std::vector<unsigned char>::iterator it = m_vectorBuffer.begin(); 
       it != m_vectorBuffer.end(); ++it){ 
      *it = m_bufferReceive[i]; 
      ++i; 
     } 
    }else{ 
     m_lengthReceive = 0; 
     m_sock->async_read_some(buffer(m_bufferReceive), 
       boost::bind(&SyncServer::tcpReceiveHandler, this, 
         boost::asio::placeholders::error, 
         boost::asio::placeholders::bytes_transferred)); 
    } 
} 

在此回調,則需要隊列中下一個讀(通常,如果沒有問題,而不是當有問題!)

+0

我已經包括了另一條道路,現在,如果有一個錯誤。但是這並不能解決問題。沒有錯誤拋出。 – cxd

+0

您的評論尚不清楚,請更新代碼。 – Nim