• boost ASIO实例


    client端代码

    #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,'',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>
    ”;
        //    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_,'',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;
    }
  • 相关阅读:
    missing requires of libmysqlclient.so.18()(64bit)
    Ambari安装HDP问题:User root is not allowed to impersonate anonymous.User: hcat is not allowed to impersonate ambari-qa
    ambari2.6.50 openssl 版本问题:SSLError: Failed to connect. Please check openssl library versions. Openssl error upon host registration
    HDP 2.6 requires libtirpc-devel
    Kafka 如何读取offset topic内容 (__consumer_offsets)
    Linux集群时间同步方法
    centos7 ambari2.6.1.5+hdp2.6.4.0 大数据集群安装部署
    Centos7.3离线(rpm方式)安装mysql服务
    ubuntu安装rpm的方法
    kerberos环境storm配置:Running Apache Storm Securely
  • 原文地址:https://www.cnblogs.com/kaishan1990/p/5195465.html
Copyright © 2020-2023  润新知