2017-05-02 45 views
1

我正在學習一些網絡編程,並被推薦使用boost-asio。我在:http://www.boost.org/doc/libs/1_64_0/doc/html/boost_asio/tutorial.html上做了Daytime Tutorials 1 & 2,並希望對其進行修改,以便服務器對發送序列化對象的客戶端作出反應,然後發回結果。我想象使用類似下面的序列,意圖是客戶端將坐在handleRead循環等待服務器完成:無法發送數據,直到套接字關閉

服務器:
接受 - > handleRead - > process_read - >執行操作 - - > handleWrite

客戶:
連接 - > handleWrite - > handleRead - > process_read

然而,當我這樣做,服務器和客戶端在某種程度上陷入讀取循環我有建立。這在客戶端是期望的,但客戶端應該在進入讀取循環之前編寫和發送數據。當我在客戶端斷開連接或將socket.close()添加到我寫入的寫入函數的末尾時,所有其餘的服務器步驟都會在客戶端發送相應數據的情況下進行。

我本來以爲這個問題曾與被啓用Nagle算法做的,但加入

boost::asio::ip::tcp::no_delay option(true); 
socket.set_option(option); 

沒有幫助的。我是否缺少教程中未提供的有關如何獲取此數據以進行發送(例如刷新套接字)的內容?

void myClient::handle_read() 
{ 
    boost::system::error_code e; 
    try 
    {  
     for (;;) 
     { 
      size_t len = boost::asio::read(socket, boost::asio::buffer(inBuffer), e); 

      std::cout << "Client Received: "; 

      if (e == boost::asio::error::eof) 
      { 
       break; 
      } 

      else if (e) 
      { 
       throw boost::system::system_error(e); 
      } 
     } 
    } 

    catch (std::exception& e) 
    { 
     std::cerr << e.what() << std::endl; 
     std::cout << e.what() << std::endl; 
    } 
} 

template <typename T> 
void handleWrite(T& t) 
{ 
    std::ostringstream archive_stream; 
    std::string tempString; 

    boost::archive::text_oarchive archive(archive_stream); 
    archive << t; 

    tempString = archive_stream.str(); 
    outBuffer.assign(tempString.begin(), tempString.end()); 

    boost::system::error_code ignored_error; 
    size_t sent = boost::asio::write(socket, boost::asio::buffer(outBuffer), ignored_error); 
    std::cout << sent << std::endl; 
} 

我對C++和網絡編程相當陌生,所以任何額外的文檔也是讚賞。謝謝!

+0

教程中的原始程序是否工作?你有什麼改變? –

+0

是的。我改變了很多東西,但我試圖完成的最重要的事情是能夠從客戶端 - >服務器 - >客戶端發送消息,而不是在連接後立即從服務器獲取消息。 – ipwnatlyfe

+0

從你的問題來看,並不清楚。我建議隔離一個最小的重大更改併發布完全相同的內容。 –

回答

1

當然,你被困在你的閱讀循環中。它不會退出直到蒸汽結束,並且流的結束僅在對等關閉插座時發生。

+0

所以我期望這個工作是服務器將坐在它handle_read()循環等待在handle_write()部分期間從客戶端接收的東西,但似乎沒有寫在handle_write()和客戶端結束在它自己的handle_read()循環中被卡住,而不會發送它所寫的內容,直到它中斷。你是說我必須在客戶端handle_write()和handle_read()之間添加一些內容才能發送消息?或者你是什麼意思? – ipwnatlyfe

+0

Data * does *被髮送,但是您的讀取循環不會退出,直到流結束或出錯。這是你的錯誤。您需要在數據到達時對其進行處理。 – EJP

+0

事情是,如果它只是保持閱讀的東西,並打印'std :: cout <<「客戶端(服務器)Received:」;'那麼這是有道理的,但它只是被困在size_t len = boost :: asio :: read(socket,boost :: asio :: buffer(inBuffer),e);線。 我不明白它會卡在那裏,如果客戶確實在寫東西的時候沒有讀取任何東西。我添加了一行來打印循環中的緩衝區,但是在套接字關閉之前,它不會執行任何操作。 – ipwnatlyfe

相關問題