Book Image

Boost.Asio C++ Network Programming Cookbook

By : Dmytro Radchuk
Book Image

Boost.Asio C++ Network Programming Cookbook

By: Dmytro Radchuk

Overview of this book

Starting with recipes demonstrating the execution of basic Boost.Asio operations, the book goes on to provide ready-to-use implementations of client and server applications from simple synchronous ones to powerful multithreaded scalable solutions. Finally, you are presented with advanced topics such as implementing a chat application, implementing an HTTP client, and adding SSL support. All the samples presented in the book are ready to be used in real projects just out of the box. As well as excellent practical examples, the book also includes extended supportive theoretical material on distributed application design and construction.
Table of Contents (13 chapters)
Boost.Asio C++ Network Programming Cookbook
Credits
About the Author
About the Reviewer
www.PacktPub.com
Preface
Index

Creating a passive socket


A passive socket or acceptor socket is a type of socket that is used to wait for connection establishment requests from remote applications that communicate over the TCP protocol. This definition has two important implications:

  • Passive sockets are used only in server applications or hybrid applications that may play both roles of the client and server.

  • Passive sockets are defined only for the TCP protocol. As the UDP protocol doesn't imply connection establishment, there is no need for a passive socket when communication is performed over UDP.

This recipe explains how to create and open a passive socket in Boost.Asio.

How to do it…

In Boost.Asio a passive socket is represented by the asio::ip::tcp::acceptor class. The name of the class suggests the key function of the objects of the class—to listen for and accept or handle incoming connection requests.

The following algorithm describes the steps required to perform to create an acceptor socket:

  1. Create an instance of the asio::io_service class or use the one that has been created earlier.

  2. Create an object of the asio::ip::tcp class that represents the TCP protocol and the required version of the underlying IP protocol (IPv4 or IPv6).

  3. Create an object of the asio::ip::tcp::acceptor class representing an acceptor socket, passing the object of the asio::io_service class to its constructor.

  4. Call the acceptor socket's open() method, passing the object representing the protocol created in step 2 as an argument.

The following code sample demonstrates the possible implementation of the algorithm. It is assumed that the acceptor socket is intended to be used over the TCP protocol and IPv6 as the underlying protocol:

#include <boost/asio.hpp>
#include <iostream>

using namespace boost;

int main()
{
  // Step 1. An instance of 'io_service' class is required by
  // socket constructor. 
  asio::io_service ios;

  // Step 2. Creating an object of 'tcp' class representing
  // a TCP protocol with IPv6 as underlying protocol.
  asio::ip::tcp protocol = asio::ip::tcp::v6();

  // Step 3. Instantiating an acceptor socket object.
  asio::ip::tcp::acceptor acceptor(ios);

  // Used to store information about error that happens
  // while opening the acceptor socket.
  boost::system::error_code ec;

  // Step 4. Opening the acceptor socket.
  acceptor.open(protocol, ec);

  if (ec.value() != 0) {
    // Failed to open the socket.
    std::cout
      << "Failed to open the acceptor socket!"
      << "Error code = "
      << ec.value() << ". Message: " << ec.message();
    return ec.value();
  }

  return 0;
}

How it works…

Because an acceptor socket is very similar to an active socket, the procedure of creating them is almost identical. Therefore, here we only shortly go through the sample code. For more details about each step and each object involved in the procedure, please refer to the Creating an active socket recipe.

In step 1, we create an instance of the asio::io_service class. This class is needed by all Boost.Asio components that need access to the services of the underlying operating system.

In step 2, we create an object representing a TCP protocol with IPv6 as its underlying protocol.

Then in step 3, we create an instance of the asio::ip::tcp::acceptor class, passing an object of the asio::io_service class as an argument to its constructor. Just as in the case of an active socket, this constructor instantiates an object of Boost.Asio the asio::ip::tcp::acceptor class, but does not allocate the actual socket object of the underlying operating system.

The operating system socket object is allocated in step 4, where we open the acceptor socket object, calling its open() method and passing the protocol object to it as an argument. If the call succeeds, the acceptor socket object is opened and can be used to start listening for incoming connection requests. Otherwise, the ec object of the boost::system::error_code class will contain error information.

See also

  • The Creating an active socket recipe provides more details about the asio::io_service and asio::ip::tcp classes