boost ASIO實例

client端代碼ios

#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
using boost::asio::ip::tcp;
class client
{
public:
    client(boost::asio::io_service& io_service,tcp::endpoint& endpoint)
        : socket(io_service)//這裏就把socket實例化了
    {
        //鏈接服務端 connect
        socket.async_connect(endpoint,
            boost::bind(&client::handle_connect,this,boost::asio::placeholders::error)
            );
        memset(getBuffer,'\0',1024);
    }
    ~client()
    {}
private:
    void handle_connect(const boost::system::error_code& error)
    {
        if(!error)
        {
            //一連上,就向服務端發送信息
            boost::asio::async_write(socket,boost::asio::buffer("hello,server!"),
                boost::bind(&client::handle_write,this,boost::asio::placeholders::error));

            /**讀取服務端發下來的信息
            *這裏很奇怪,用async_read根本就不能進入handle_read函數
            **/

            // --已經解決,boost::asio::async_read(...)讀取的字節長度不能大於數據流的長度,不然就會進入
            // ioservice.run()線程等待,read後面的就不執行了。
            //boost::asio::async_read(socket,
            //     boost::asio::buffer(getBuffer,1024),
            //     boost::bind(&client::handle_read,this,boost::asio::placeholders::error)
            //    );
            socket.async_read_some(boost::asio::buffer(getBuffer,1024),
                boost::bind(&client::handle_read,this,boost::asio::placeholders::error)
                );
        }
        else
        {
            socket.close();
        }
    }
    void handle_read(const boost::system::error_code& error)
    {
        if(!error)
        {
            std::cout << getBuffer << std::endl;
            //boost::asio::async_read(socket,
            //         boost::asio::buffer(getBuffer,1024),
            //         boost::bind(&client::handle_read,this,boost::asio::placeholders::error)
            //        );

            //這樣就能夠實現循環讀取了,至關於while(1)
            //固然,到了這裏,作過網絡的朋友就應該至關熟悉了,一些邏輯就能夠自行擴展了
            //想作聊天室的朋友能夠用多線程來實現
            socket.async_read_some(
                boost::asio::buffer(getBuffer,1024),
                boost::bind(&client::handle_read,this,boost::asio::placeholders::error)
                );
        }
        else
        {
            socket.close();
        }
    }
    void handle_write(const boost::system::error_code& error)
    {
    }

private:
    tcp::socket socket;
    char getBuffer[1024];
};

int main(int argc,char* argv[])
{
    //if(argc != 3)
    //{
    // std::cerr << 「Usage: chat_client <host> <port>\n」;
    //    return 1;
    //}

    //我覺IO_SERVICE是一個基本性的接口,基本上一般用到的類實例都須要經過它來構造
    //功能咱們能夠看似socket
    boost::asio::io_service io_service;
    //這個終端就是服務器
    //它的定義就能夠看做時sockaddr_in,咱們用它來定義IP和PORT
    tcp::endpoint endpoint(boost::asio::ip::address_v4::from_string("127.0.0.1"/*argv[1]*/),8100/*argv[2]*/);
    //既然socket和sockaddr_in已經定義好了,那麼,就能夠CONNECT了
    //之因此爲了要把鏈接和數據處理封成一個類,就是爲了方便管理數據,這點在服務端就會有明顯的感受了
    boost::shared_ptr<client> client_ptr(new client(io_service,endpoint));
    //執行收發數據的函數
    io_service.run();
    return 0;
}

客戶端代碼服務器

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <iostream>
using boost::asio::ip::tcp;
#define max_len 1024
class clientSession
    :public boost::enable_shared_from_this<clientSession>
{
public:
    clientSession(boost::asio::io_service& ioservice)
        :m_socket(ioservice)
    {
        memset(data_,'\0',sizeof(data_));
    }
    ~clientSession()
    {}
    tcp::socket& socket()
    {
        return m_socket;
    }
    void start()
    {
        boost::asio::async_write(m_socket,
            boost::asio::buffer("link successed!"),
            boost::bind(&clientSession::handle_write,shared_from_this(),
            boost::asio::placeholders::error));

        /*async_read跟客戶端同樣,仍是不能進入handle_read函數,若是你能找到問題所在,請告訴我,謝謝*/

        // --已經解決,boost::asio::async_read(...)讀取的字節長度不能大於數據流的長度,不然就會進入
        // ioservice.run()線程等待,read後面的就不執行了。
        //boost::asio::async_read(m_socket,boost::asio::buffer(data_,max_len),

        //         boost::bind(&clientSession::handle_read,shared_from_this(),

        //         boost::asio::placeholders::error));
        //max_len能夠換成較小的數字,就會發現async_read_some能夠連續接收未收完的數據

        m_socket.async_read_some(boost::asio::buffer(data_,max_len),
            boost::bind(&clientSession::handle_read,shared_from_this(),
            boost::asio::placeholders::error));
    }
private:
    void handle_write(const boost::system::error_code& error)
    {

        if(error)
        {
            m_socket.close();
        }

    }
    void handle_read(const boost::system::error_code& error)
    {

        if(!error)
        {
            std::cout << data_ << std::endl;
            //boost::asio::async_read(m_socket,boost::asio::buffer(data_,max_len),

            //     boost::bind(&clientSession::handle_read,shared_from_this(),

            //     boost::asio::placeholders::error));

            m_socket.async_read_some(boost::asio::buffer(data_,max_len),
                boost::bind(&clientSession::handle_read,shared_from_this(),
                boost::asio::placeholders::error));
        }
        else
        {
            m_socket.close();
        }

    }
private:
    tcp::socket m_socket;
    char data_[max_len];
};

class serverApp
{
    typedef boost::shared_ptr<clientSession> session_ptr;
public:
    serverApp(boost::asio::io_service& ioservice,tcp::endpoint& endpoint)
        :m_ioservice(ioservice),
        acceptor_(ioservice,endpoint)
    {
        session_ptr new_session(new clientSession(ioservice));
        acceptor_.async_accept(new_session->socket(),
            boost::bind(&serverApp::handle_accept,this,boost::asio::placeholders::error,
            new_session));
    }
    ~serverApp()
    {
    }
private:
    void handle_accept(const boost::system::error_code& error,session_ptr& session)
    {
        if(!error)
        {
            std::cout << "get a new client!" << std::endl;
            //實現對每一個客戶端的數據處理

            session->start();
            //在這就應該看出爲何要封session類了吧,每個session就是一個客戶端

            session_ptr new_session(new clientSession(m_ioservice));
            acceptor_.async_accept(new_session->socket(),
                boost::bind(&serverApp::handle_accept,this,boost::asio::placeholders::error,
                new_session));
        }
    }
private:
    boost::asio::io_service& m_ioservice;
    tcp::acceptor acceptor_;
};

int main(int argc , char* argv[])
{
    boost::asio::io_service myIoService;
    short port = 8100/*argv[1]*/;
    //咱們用的是inet4

    tcp::endpoint endPoint(tcp::v4(),port);
    //終端(能夠看做sockaddr_in)完成後,就要accept了

    serverApp sa(myIoService,endPoint);
    //數據收發邏輯

    myIoService.run();
    return 0;
}
相關文章
相關標籤/搜索