Boost: ASIO Connection Management 1

Source: Internet
Author: User
Tags localhost 8888

After completing the first boost: ASIO-based communication service program, review the concepts used and refer to some materials. We will use a series to summarize how to write high-performance TCP service programs through boost: ASIO.

This article describes how to listen to a port and receive connection requests from a single thread. At the same time, the previous "elegant exit" code is also reused.

First, the main function creates a server object. The server object is responsible for listening to the local port 8888. Once a connection request exists, it creates a connection object and calls startwork to start work.

The following code is used:

#include <cstdlib>#include <boost/asio.hpp>#include <boost/bind.hpp>#include <iostream>using namespace boost;using namespace boost::asio;using ip::tcp;using namespace std;using boost::system::error_code;class Connection {public:    Connection(io_service& s): socket(s) {            }        ~Connection() {        socket.close();        cout << "~Connection" << endl;    }        void StartWork() {        cout << "The new connection object is starting now." << endl;    }    public:    tcp::socket socket;};class Server {public:    Server(io_service & s, tcp::endpoint const& listen_endpoint)    : io_(s), signals_(s), acceptor_(s, listen_endpoint) {        signals_.add(SIGINT);        signals_.add(SIGTERM);#if defined(SIGQUIT)        signals_.add(SIGQUIT);#endif        signals_.async_wait(boost::bind(&Server::Stop, this));        shared_ptr<Connection> c(new Connection(io_));        cout << "count1:" << c.use_count() << endl;        acceptor_.async_accept(c->socket,                boost::bind(&Server::AfterAccept, this, c, _1));        cout << "count2:" << c.use_count() << endl;    }    void Run() {        io_.run();    }    void AfterAccept(shared_ptr<Connection>& c, error_code const& ec) {        // Check whether the server was stopped by a signal before this completion        // handler had a chance to run.        if (!acceptor_.is_open()) {            return;        }                cout << "count3:" << c.use_count() << endl;                if (!ec) {            c->StartWork();            shared_ptr<Connection> c2(new Connection(io_));            acceptor_.async_accept(c2->socket,                    boost::bind(&Server::AfterAccept, this, c2, _1));        }    }private:    void Stop() {        cout << "stop io_service" << endl;        io_.stop();    }private:    io_service& io_;    boost::asio::signal_set signals_;    tcp::acceptor acceptor_;};int main(int argc, char** argv) {    io_service s;    tcp::endpoint listen_endpoint(tcp::v4(), 8888);    Server server(s, listen_endpoint);    server.Run();    return 0;}

The Code is a little long, but it is very simple with the real product.

Run the Telnet localhost 8888 command to quickly test the connection. The connection is established and quickly disconnected.

The program prints two lines of messages:

The new connection object is starting now.~Connection

This is related to the object lifecycle.

First, let's look at the server constructor. A connection object is created and managed using shared_ptr. At this time, the reference count is 1. Then, when we call bind in the following sentence, save the C variable to bind_t. Therefore, the reference count is increased to 2. Then the constructor ends and the reference count is reduced to 1.

When ASIO calls back the operator () of the bind_t object, it will eventually call the afteraccept function. The C object is passed in as a reference parameter, so the reference count is not added for parameter passing. However, the ASIO callback mechanism increases the reference count to 2.

Then startwork is run, and startwork Returns quickly. When the afteraccept function exits, the ASIO callback mechanism reduces the reference count to 1, and the function object bind_t is also destroyed, so the reference count is reduced to 0, therefore, the destructor of C is called.

The internal details of the BIND do not care about it. Here, you only need to note that once the startwork function exits, the object will be destroyed.

Since the afteraccept function always calls the async_accept function again at the end, it will keep waiting for new connections. The entire program is ended only when the io_service: Stop function is called.

This simple example shows how a connection is established and the lifecycle of a connection object is so fragile. Improvements will be made later.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.