2012-02-19 30 views
3

我完全看樣品是:需要解釋明白ASIO REFERENCE_COUNTED例如

#include <boost/asio.hpp> 
#include <boost/bind.hpp> 
#include <boost/enable_shared_from_this.hpp> 
#include <boost/shared_ptr.hpp> 
#include <iostream> 
#include <vector> 

using boost::asio::ip::tcp; 

// A reference-counted non-modifiable buffer class. 
class shared_const_buffer 
{ 
public: 
    // Construct from a std::string. 
    explicit shared_const_buffer(const std::string& data) 
    : data_(new std::vector<char>(data.begin(), data.end())), 
     buffer_(boost::asio::buffer(*data_)) 
    { 
    } 
    // Implement the ConstBufferSequence requirements. 
    typedef boost::asio::const_buffer value_type; 
    typedef const boost::asio::const_buffer* const_iterator; 
    const boost::asio::const_buffer* begin() const { return &buffer_; } 
    const boost::asio::const_buffer* end() const { return &buffer_ + 1; } 

private: 
    boost::shared_ptr<std::vector<char> > data_; 
    boost::asio::const_buffer buffer_; 
}; 

class session 
    : public boost::enable_shared_from_this<session> 
{ 
public: 
    session(boost::asio::io_service& io_service) 
    : socket_(io_service) 
    { 
    } 

    tcp::socket& socket() 
    { 
    return socket_; 
    } 

    void start() 
    { 
    using namespace std; // For time_t, time and ctime. 
    time_t now = time(0); 
    shared_const_buffer buffer(ctime(&now)); 
    boost::asio::async_write(socket_, buffer, 
     boost::bind(&session::handle_write, shared_from_this())); 
    } 

    void handle_write() 
    { 
    } 

private: 
    // The socket used to communicate with the client. 
    tcp::socket socket_; 
}; 

typedef boost::shared_ptr<session> session_ptr; 

class server 
{ 
public: 
    server(boost::asio::io_service& io_service, short port) 
    : io_service_(io_service), 
     acceptor_(io_service, tcp::endpoint(tcp::v4(), port)) 
    { 
    session_ptr new_session(new session(io_service_)); 
    acceptor_.async_accept(new_session->socket(), 
     boost::bind(&server::handle_accept, this, new_session, 
      boost::asio::placeholders::error)); 
    } 

    void handle_accept(session_ptr new_session, 
     const boost::system::error_code& error) 
    { 
    if (!error) 
    { 
     new_session->start(); 
    } 

    new_session.reset(new session(io_service_)); 
    acceptor_.async_accept(new_session->socket(), 
     boost::bind(&server::handle_accept, this, new_session, 
      boost::asio::placeholders::error)); 
    } 

private: 
    boost::asio::io_service& io_service_; 
    tcp::acceptor acceptor_; 
}; 

int main(int argc, char* argv[]) 
{ 
    try 
    { 
    if (argc != 2) 
    { 
     std::cerr << "Usage: reference_counted <port>\n"; 
     return 1; 
    } 

    boost::asio::io_service io_service; 

    using namespace std; // For atoi. 
    server s(io_service, atoi(argv[1])); 

    io_service.run(); 
    } 
    catch (std::exception& e) 
    { 
    std::cerr << "Exception: " << e.what() << "\n"; 
    } 

    return 0; 
} 

我是一個Java程序員想了解如何提高ASIO的工作,有幾點我需要幫助。我的問題是:

  1. 在這些線路:

    const boost::asio::const_buffer* begin() const { return &buffer_; } 
    const boost::asio::const_buffer* end() const { return &buffer_ + 1; } 
    

    shared_const_buffer是使用到async_write以後,所以我覺得應該實現某種緩衝,但我沒有看到任何繼承簽名。那麼定義begin()end()夠了嗎?

  2. 而在這些線路:

    shared_const_buffer buffer(ctime(&now)); 
    boost::asio::async_write(socket_, buffer, 
             boost::bind(&session::handle_write, 
                shared_from_this()));  
    

    share_const_buffer具有data_是一個共享的指針,而不是它本身,怎麼會是buffer有效期至async_write實際寫入數據?

回答

1

shared_const_buffer是使用async_write()以後,所以我覺得它應該 實現某種緩衝,但我沒有看到任何繼承 簽名。那麼定義begin()end()夠了嗎?

shared_const_buffer類使用的緩衝液是其_data構件,boost::shared_ptr<std::vector<char> >。將迭代器公開到緩衝區足以與async_write()一起使用。

share_const_buffer具有data_是一個共享的指針,而不是它本身,如何 是緩衝有效期至async_write()實際寫入數據?

shared_const_buffer類實現了ASIO ConstBufferSequence型需求

// Implement the ConstBufferSequence requirements. 
    typedef boost::asio::const_buffer value_type; 
    typedef const boost::asio::const_buffer* const_iterator; 
    const boost::asio::const_buffer* begin() const { return &buffer_; } 
    const boost::asio::const_buffer* end() const { return &buffer_ + 1; } 

所以調用async_write當它被複制時,documentation明確指出這一點:

緩衝區

一或更多的緩衝區包含輸入要寫入的數據。 雖然可以根據需要複製緩衝區對象,但調用程序保留底層內存塊的所有權,必須保證它們在調用處理程序前保持有效。

但是,底層數據不會被複制,因爲它保留在shared_ptr中。你可以看到,這可以通過灑一些調試語句

--- reference_counted.cpp 2012-02-19 08:30:32.000000000 -0600 
+++ reference_counted_good.cpp 2012-02-19 08:26:27.000000000 -0600 
@@ -26,9 +26,7 @@ 
    : data_(new std::vector<char>(data.begin(), data.end())), 
     buffer_(boost::asio::buffer(*data_)) 
    { 
-  std::cout << "shared_const_buffer()" << std::endl; 
    } 
- ~shared_const_buffer() { std::cout << "~shared_const_buffer() buffer use count: " << data_.use_count() << std::endl; } 

    // Implement the ConstBufferSequence requirements. 
    typedef boost::asio::const_buffer value_type; 
@@ -66,7 +64,6 @@ 

    void handle_write() 
    { 
-  std::cout << "handle_write" << std::endl; 
    } 

private: 

,並在另一個shell

Sam-Millers-MacBook-Pro:stackoverflow samm$ telnet localhost 1234 
Trying ::1... 
telnet: connect to address ::1: Connection refused 
Trying 127.0.0.1... 
Connected to localhost. 
Escape character is '^]'. 
Sun Feb 19 08:22:56 2012 
Connection closed by foreign host. 
Sam-Millers-MacBook-Pro:stackoverflow samm$ 

運行它

Sam-Millers-MacBook-Pro:stackoverflow samm$ ./a.out 1234 
shared_const_buffer() 
~shared_const_buffer() buffer use count: 8 
~shared_const_buffer() buffer use count: 7 
~shared_const_buffer() buffer use count: 6 
~shared_const_buffer() buffer use count: 5 
~shared_const_buffer() buffer use count: 4 
~shared_const_buffer() buffer use count: 3 
~shared_const_buffer() buffer use count: 3 
~shared_const_buffer() buffer use count: 2 
handle_write 
~shared_const_buffer() buffer use count: 2 
~shared_const_buffer() buffer use count: 1 

可以看到這樣的實際緩衝區一直有效,直到最後shared_const_buffer去超出範圍並運行描述符

+0

okie,在java世界中,shared_const_buffer需要我實現一種緩衝區,以便將其轉換爲基類型,並調用接口方法來獲取緩衝區。在C++中的shared_const_buffer的情況下它如何工作? – secmask 2012-02-19 16:30:18

+0

我創建了另一個測試,C++不需要類型檢查,這就是爲什麼shared_const_buffer不需要顯式實現接口。 – secmask 2012-02-19 16:55:56

+0

@secmask我不會建議接近一個C++編程項目,假設它應該像Java一樣行事。 – 2012-02-19 21:59:52