Boost.asio實現的同步、異步TCP通信的簡單例子

每個asio程序都必須有io_server對象。對於服務端和客戶端都需要socket對象,通過socket對象的成員函數進行連接和數據通信。服務端需要 acceptor對象來等待連接。

下面的例子是用C++11和boost1.57編寫的。

同步TCP通信服務端

#include <boost/asio.hpp>
#include <iostream>
using namespace boost::asio;
int main()
{
    try
    {
        io_service io;
        ip::tcp::endpoint ep(ip::tcp::v4(), 6688);
        ip::tcp::acceptor acceptor(io, ep);
        while (1)
        {
            ip::tcp::socket sock(io);
            acceptor.accept(sock);
            std::cout << "client:" << sock.remote_endpoint().address() << std::endl;
            sock.write_some(buffer("hello asio"));
        }
    }
    catch (std::exception& e)
    {
        std::cout << e.what() << std::endl;
    }
    return 0;
}

同步Tcp通信客戶端

#include <boost/asio.hpp>
#include <iostream>
#include <vector>
#include <string>
using namespace boost::asio;
int main()
{
    try
    {
        io_service io;
        ip::tcp::endpoint ep(ip::address::from_string("127.0.0.1"), 6688);
        ip::tcp::socket sock(io);
        sock.connect(ep);
        char str[1024];
        sock.read_some(buffer(str));
        std::cout << "receive from" << sock.remote_endpoint().address() << std::endl;;
        std::cout << str << std::endl;
    }
    catch (std::exception& e)
    {
        std::cout << e.what() << std::endl;
    }
    getchar();
    return 0;
}

運行結果
這裏寫圖片描述

異步TCP服務端

#include <boost/asio.hpp>
#include <iostream>
using namespace boost::asio;
class Server
{
    typedef ip::tcp::socket socket_type;
    typedef std::shared_ptr<socket_type> sock_ptr;
public:
    Server() :m_acceptor(m_io, ip::tcp::endpoint(ip::tcp::v4(), 6688))
    {
        accept();
    }
    void run()
    {
        m_io.run();
    }
private:
    void accept()
    {
        sock_ptr sock(new socket_type(m_io));
        m_acceptor.async_accept(*sock,
            std::bind(&Server::accept_handler, this, std::placeholders::_1, sock));
    }
    void accept_handler(const boost::system::error_code& ec, sock_ptr sock)
    {
        if (ec)
        {return;}
        std::cout << "client:";
        std::cout << sock->remote_endpoint().address() << std::endl;
        sock->async_write_some(buffer("hello asio"),
            std::bind(&Server::write_handler, this, std::placeholders::_1));
        accept();
    }
    void write_handler(const boost::system::error_code&)
    {
        std::cout << "send msg complete." << std::endl;
    }
private:
    io_service m_io;
    ip::tcp::acceptor m_acceptor;
};
int main()
{
    try
    {
        std::cout << "server" << std::endl;
        Server svr;
        svr.run();
    }
    catch (std::exception& e)
    {
        std::cout << e.what() << std::endl;
    }
    return 0;
}

異步TCP通信客戶端

#include <boost/asio.hpp>
#include <iostream>
using namespace boost::asio;
class Client
{
    typedef ip::tcp::socket socket_type;
    typedef std::shared_ptr<socket_type> sock_ptr;
public:
    Client() :m_ep(ip::address::from_string("127.0.0.1"), 6688)
    {
        start();
    }
    void run()
    {
        m_io.run();
    }
private:
    void start()
    {
        sock_ptr sock(new socket_type(m_io));
        sock->async_connect(m_ep, std::bind(&Client::connect_handler, this, std::placeholders::_1, sock));
    }
    void connect_handler(const boost::system::error_code& ec, sock_ptr sock)
    {
        if (ec)
        {return;}
        std::cout << "receive from:" << sock->remote_endpoint().address() << std::endl;
        sock->async_read_some(buffer(m_buf),
            std::bind(&Client::read_handler, this, std::placeholders::_1));
    }
    void read_handler(const boost::system::error_code& ec)
    {
        if (ec)
        {return;}
        std::cout << m_buf << std::endl;
    }
private:
    io_service m_io;
    ip::tcp::endpoint m_ep;
    enum { max_length = 1024 };
    char m_buf[max_length];
};
int main()
{
    try
    {
        std::cout << "client start." << std::endl;
        Client cl;
        cl.run();
    }
    catch (std::exception& e)
    {
        std::cout << e.what() << std::endl;
    }
    getchar();
    return 0;
}

運行結果
這裏寫圖片描述

可以使用lamdba簡化異步TCP程序。
服務端

#include <boost/asio.hpp>
#include <iostream>
using namespace boost::asio;
class Server
{
    typedef ip::tcp::socket socket_type;
    typedef std::shared_ptr<socket_type> sock_ptr;
public:
    Server() :m_acceptor(m_io, ip::tcp::endpoint(ip::tcp::v4(), 6688))
    {
        accept();
    }
    void run()
    {
        m_io.run();
    }
private:
    void accept()
    {
        sock_ptr sock(new socket_type(m_io));
        m_acceptor.async_accept(*sock,
        [this, sock](const boost::system::error_code& ec)
        {
            if (ec)
            {
                return;
            }
            std::cout << "client:";
            std::cout << sock->remote_endpoint().address() << std::endl;
            sock->async_write_some(buffer("hello asio"),
                [](const boost::system::error_code&, std::size_t)
                {
                    std::cout << "send msg complete." << std::endl;
                });
            accept();
        });
    }
private:
    io_service m_io;
    ip::tcp::acceptor m_acceptor;
};
int main()
{
    try
    {
        std::cout << "server" << std::endl;
        Server svr;
        svr.run();
    }
    catch (std::exception& e)
    {
        std::cout << e.what() << std::endl;
    }
    return 0;
}

客戶端

#include <boost/asio.hpp>
#include <iostream>
using namespace boost::asio;
class Client
{
    typedef ip::tcp::socket socket_type;
    typedef std::shared_ptr<socket_type> sock_ptr;
public:
    Client() :m_ep(ip::address::from_string("127.0.0.1"), 6688)
    {
        start();
    }
    void run()
    {
        m_io.run();
    }
private:
    void start()
    {
        sock_ptr sock(new socket_type(m_io));
        sock->async_connect(m_ep, 
            [this, sock](const boost::system::error_code& ec)
        {
            if (ec)
            {
                return;
            }
            std::cout << "receive from:" << sock->remote_endpoint().address() << std::endl;
            sock->async_read_some(buffer(m_buf),
                [this](const boost::system::error_code& ec, std::size_t)
            {
                if (ec)
                {
                    return;
                }
                std::cout << m_buf << std::endl;
            });
        });
    }
private:
    io_service m_io;
    ip::tcp::endpoint m_ep;
    enum { max_length = 1024 };
    char m_buf[max_length];
};
int main()
{
    try
    {
        std::cout << "client start." << std::endl;
        Client cl;
        cl.run();
    }
    catch (std::exception& e)
    {
        std::cout << e.what() << std::endl;
    }
    getchar();
    return 0;
}

運行結果跟上一個一樣。
詳細參考《Boost程序庫完全開發指南》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章