boost asio for sync server keeping TCP session open (with google proto buffers)

后端 未结 2 1037
甜味超标
甜味超标 2021-02-04 19:03

I currently have a very simple boost::asio server that sends a status update upon connecting (using google proto buffers):

try
{
  boost::asio::io_service io_ser         


        
2条回答
  •  执念已碎
    2021-02-04 19:41

    In case anyone else wants to do this, here is the minimum to get above going: (similar to the tutorials, but a bit shorter and a bit different)

    class Session : public boost::enable_shared_from_this
    {
        tcp::socket socket;
        char buf[1000];
    public:
        Session(boost::asio::io_service& io_service)
            : socket(io_service) { }
        tcp::socket& SocketRef() { return socket; }
        void Read() {
            boost::asio::async_read( socket,boost::asio::buffer(buf),boost::asio::transfer_at_least(1),boost::bind(&Session::Handle_Read,shared_from_this(),boost::asio::placeholders::error));
        }
        void Handle_Read(const boost::system::error_code& error) {
            if (!error)
            {
                //read from buffer and handle requests
                //if you want to write sth, you can do it sync. here: e.g. boost::asio::write(socket, ..., ignored_error);
                Read();
            }
        }
    };
    
    typedef boost::shared_ptr SessionPtr;
    
    class Server
    {
        boost::asio::io_service io_service;
        tcp::acceptor acceptor;
    public:
        Server() : acceptor(io_service,tcp::endpoint(tcp::v4(), 13)) { }
        ~Server() { }
        void operator()() { StartAccept(); io_service.run(); }
        void StartAccept() {
            SessionPtr session_ptr(new Session(io_service));
            acceptor.async_accept(session_ptr->SocketRef(),boost::bind(&Server::HandleAccept,this,session_ptr,boost::asio::placeholders::error));
        }
        void HandleAccept(SessionPtr session,const boost::system::error_code& error) {
            if (!error)
              session->Read();
            StartAccept();
        }
    };
    

    From what I gathered through trial and error and reading: I kick it off in the operator()() so you can have it run in the background in an additional thread. You run one Server instance. To handle multiple clients, you need an extra class, I called this a session class. For asio to clean up dead sessions, you need a shared pointer as pointed out above. Otherwise the code should get you started.

提交回复
热议问题