2013-07-05 97 views
0

我希望實現一個全雙工tcp流。這是一個例子。boost :: tcp :: iostream同時讀取和寫入

//server.cpp 

#include <SDKDDKVer.h> 
#include <iostream> 
using namespace std; 
#include <boost/asio.hpp> 
#include <boost/thread.hpp> 

boost::asio::ip::tcp::iostream SocketStream; 

void ThreadA() 
{ 
    for(;;) 
    { 
     std::string Line; 
     std::getline(SocketStream, Line); //Y 
     std::cout << Line << std::endl; 
    } 
} 

void ThreadB() 
{ 
    for(;;) 
    { 
     std::string Line; 
     std::getline(std::cin, Line);  //Z 
     SocketStream<<Line<<std::endl; //X 
    } 
} 

int main() 
{ 
    boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 4444); 
    boost::asio::io_service io_service; 
    boost::asio::ip::tcp::acceptor acceptor(io_service, endpoint); 
    boost::system::error_code ec; 
    acceptor.accept(*SocketStream.rdbuf(), ec); 

    boost::thread tA(ThreadA); 
    boost::thread tB(ThreadB); 
    tA.join(); 
    tB.join(); 
    return 0; 
} 

//client.cpp 

#include <SDKDDKVer.h> 
#include <iostream> 
using namespace std; 
#include <boost/asio.hpp> 
#include <boost/thread.hpp> 


boost::asio::ip::tcp::iostream SocketStream; 

void ThreadA() 
{ 
    for(;;) 
    { 
     std::string Line; 
     std::getline(SocketStream, Line);  
     std::cout << Line << std::endl; 
    } 
} 

void ThreadB() 
{ 
    for(;;) 
    { 
     std::string Line; 
     std::getline(std::cin, Line);  
     SocketStream<<Line<<std::endl;  
    } 
} 

int main() 
{ 
    boost::system::error_code ec; 
    SocketStream.connect("127.0.0.1", "4444"); 

    boost::thread tA(ThreadA); 
    //boost::thread tB(ThreadB); 
    tA.join(); 
    //tB.join(); 
    return 0; 
} 

但它會阻塞線X
Q1,我是不是做錯了什麼或者是boost::asio::ip::tcp::iostream根本不能這樣做呢?
Q2,如果boost::asio::ip::tcp::iostream不足以完成任務,我還應該使用哪些東西?
我看到boost::iostream具有雙向模式。那是我在找什麼?我不熟悉boost::iostream,所以我不確定它的真實含義。
如果boost::iostream失敗,那麼我必須使用boost::asio的異步操作嗎?因爲我想讓套接字的行爲像一個流,並且包裝異步操作可能很困難。

附加的:我希望的是SocketStream可以被寫入,同時它也在讀取時被阻塞,這意味着該流是全雙工的。

請任何意見,將不勝感激!

+0

此行阻止了哪一行?你可以顯示你的代碼初始化SocketStream嗎? – crowder

+0

@crowder完成! – Immueggpain

+0

好的,下一步:你如何啓動線程? – crowder

回答

1

boost::asio類的實例不是線程安全的(io_service只是異常)。所以你不能在2個線程中使用單個的boost::asio::ip::tcp::iostream實例。

要做這個任務,我寧願使用異步操作和額外的線程來讀取標準輸入,因爲這是讀取阻塞。所以,線程之一getline from stdin和asio :: write to peer。其他線程使用async_read_until讀取,直到接收到\r\n。此外,您的服務器似乎無法與多個對等設備一起工作,因此您可以使用async_accept

+0

謝謝你,upvoted。你的意思是說,使用iostream風格來達到這個目的是不可能的? – Immueggpain

+0

@Iueueggpain我沒有使用iostream風格的經驗,但我認爲它不是線程安全的,所以你不能在很多線程中使用它。 – PSIAlt

+0

然後是否可以在'boost :: asio'中使用'boost :: iostream'來創建流接口?我目前使用2'tcp :: stream's,但這意味着2個TCP連接... – Immueggpain