2011-03-24 68 views
2

好的傳球,這是我當前的代碼片段:周圍的boost ::支持ASIO :: IP :: TCP ::插座

namespace bai = boost::asio::ip; 
bai::tcp::socket tcp_connect(std::string hostname, std::string port) { 
    try { 
     boost::asio::io_service io_service; 
     bai::tcp::resolver resolver(io_service); 

     // we now try to get a list of endpoints to the server 
     bai::tcp::resolver::query query(hostname, port); 
     bai::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); 
     bai::tcp::resolver::iterator end; 

     // looking for a successful endpoint connection 
     bai::tcp::socket socket(io_service); 
     boost::system::error_code error = boost::asio::error::host_not_found; 
     while (error && endpoint_iterator != end) { 
      socket.close(); 
      socket.connect(*endpoint_iterator++ , error); 
     } 

     if (error) throw boost::system::system_error(error); 

     return socket; 
    } catch (std::exception &ex) { 
     std::cout << "Exception: " << ex.what() << "\n"; 
    } 
} 

應返回上一個port連接boost::asio::ip::tcp::sockethostname。不過,我得到了一大堆難以理解的boost::noncopyable錯誤。但是我的問題是,那麼我應該怎樣通過這些套接字呢?這有什麼問題?

回答

11

socket無法複製。改爲使用boost::shared_ptr<bai::tcp::socket>。如果你可能複製一個套接字,你會有各種有趣的問題,如果你最終有兩個socket實例代表相同的底層操作系統套接字 - 所以它是有道理的複製(並因此返回值,傳值)是不允許。

+0

我以前從來沒有用過'share_ptr',像這樣? 'boost :: shared_ptr tcp_connect(std :: string hostname,std :: string port)' – orlp 2011-03-24 21:27:27

+0

'boost :: shared_ptr tcp_connect(... 。)'然後'boost :: shared_ptr 套接字(new bai :: tcp :: socket(io_service));' – Erik 2011-03-24 21:28:43

+0

好吧,那有效。這意味着我必須將'socket.some_method()'的每個實例更改爲'(* socket).some_method()'? – orlp 2011-03-24 21:37:26

3

代碼:

return socket; 

企圖使插座返回的副本,然後銷燬原始套接字函數退出的時候。不幸的是,套接字不能被複制(它們管理必須關閉的底層操作系統資源,因此係統必須確保只有一個對該資源的引用存在,否則當第一個副本超出範圍時會出錯)。

正如在其他答案中所建議的那樣,您可以使用指針返回在堆上創建的對象(應該使用shared_ptr來管理對象,或者如果僅在單個地方使用unique_ptr,則更有效)或者,如果你使用的是C++ 11,你可以使用移動的構造函數的返回值:

return std::move (socket); 

這樣可避免必需使用堆分配和指針,所以很可能是最好的解決辦法。

相關問題