二級(jí)C++技巧:boost的網(wǎng)絡(luò)庫(kù)asio

字號(hào):

boost在1.35版本之后終于加入了網(wǎng)絡(luò)庫(kù)asio。春節(jié)期間終于得閑能夠一窺究竟,同時(shí)將boost.asio和知名的ACE框架做一下比較。
    asio的名字突出了異步I/O的能力,從asio的文檔中看到它使用了和ACE Proactor框架中相似的Proactor模式??荚嚧筇崾綜SDN上也有很多網(wǎng)友也寫(xiě)了很多關(guān)于異步I/O的好文章,但是還是決定從同步I/O開(kāi)始。盡管阻塞I/O不是那么酷那么絢麗但是在網(wǎng)絡(luò)編程中它和異步I/O一樣重要。
    下面是一個(gè)簡(jiǎn)單的同步I/O的例子,使用的是鎖步(lock-step)方式的通訊。
    view plaincopy to clipboardprint?
    #include
    #include "boost/asio.hpp"
    #include "boost/lexical_cast.hpp"
    using namespace std;
    using namespace boost;
    using boost::asio::ip::tcp;
    using boost::asio::io_service;
    class Client
    {
    public:
    Client (const string & hostname, unsigned short port);
    virtual ~Client ();
    // methods
    virtual void send (const string & message);
    virtual string recv ();
    virtual void close ();
    private:
    io_service * io_service_;
    tcp::socket * socket_;
    };
    Client::Client (const string & hostname, unsigned short port)
    {
    io_service_ = new io_service();
    socket_ = new tcp::socket(*io_service_);
    tcp::resolver resolver(*io_service_);
    tcp::resolver::query query(hostname, boost::lexical_cast(port));
    boost::system::error_code ec;
    tcp::resolver::iterator iter = resolver.resolve(query, ec);
    tcp::resolver::iterator end;
    // pick the first endpoint
    if (iter != end && ec == 0)
    {
    tcp::endpoint endpoint = *iter;
    std::cout << "Connecting to: " << endpoint << std::endl;
    socket_->connect(endpoint, ec);
    if (ec)
    {
    std::cerr << "Error: " << ec << std::endl;
    throw ec;
    }
    }
    }
    Client::~Client ()
    {
    delete socket_;
    delete io_service_;
    }
    void Client::send (const string & message)
    {
    boost::asio::const_buffers_1 request(message.data(), message.size());
    socket_->send(request);
    }
    string Client::recv ()
    {
    char response[128];
    size_t num = socket_->receive(boost::asio::buffer(response));
    if (num > 0)
    {
    return string (response, num);
    }
    return "";
    }
    void Client::close ()
    {
    socket_->close();
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
    Client client ("localhost", 2009);
    std::cout << client.recv() << endl;
    string request;
    do
    {
    std::cout << "Request: ";
    std::cin >> request;
    if (request == "q")
    break;
    client.send (request);
    std::cout << "Response: " << client.recv() << endl;
    }
    while (true);
    client.close();
    return 0;
    }