boost::asio::ip::tcp實現網絡通信的小例子

我稍稍整理了下,就是加了點註釋,很基本的東西,大家可以參考socket的幾個流程,我上面也有提示的,希望對大家有所幫助。最後,如果大家有什麼好的方法希望能讓我也分享下,謝謝!

服務端:

#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;

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