Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Boost.Asio C++ Network Programming Cookbook

You're reading from   Boost.Asio C++ Network Programming Cookbook Over 25 hands-on recipes to create robust and highly-efficient cross-platform distributed applications with the Boost.Asio library

Arrow left icon
Product type Paperback
Published in Jan 2016
Publisher
ISBN-13 9781783986545
Length 248 pages
Edition 1st Edition
Languages
Concepts
Arrow right icon
Author (1):
Arrow left icon
Dmytro Radchuk Dmytro Radchuk
Author Profile Icon Dmytro Radchuk
Dmytro Radchuk
Arrow right icon
View More author details
Toc

Binding a socket to an endpoint

Before an active socket can communicate with a remote application or a passive socket can accept incoming connection requests, they must be associated with a particular local IP address (or multiple addresses) and a protocol port number, that is, an endpoint. The process of associating a socket with a particular endpoint is called binding. When a socket is bound to an endpoint, all network packets coming into the host from the network with that endpoint as their target address will be redirected to that particular socket by the operating system. Likewise, all the data coming out from a socket bound to a particular endpoint will be output from the host to the network through a network interface associated with the corresponding IP address specified in that endpoint.

Some operations bind unbound sockets implicitly. For example, an operation that connects an unbound active socket to a remote application, binds it implicitly to an IP address and a protocol port number chosen by the underlying operating system. Usually, the client application doesn't need to explicitly bind an active socket to a specific endpoint just because it doesn't need that specific endpoint to communicate with the server; it only needs any endpoint for that purpose. Therefore, it usually delegates the right to choose the IP address and the port number to which the socket should be bound to the operating system. However, in some special cases, the client application might need to use a specific IP address and a protocol port number to communicate with the remote application and therefore will bind its socket explicitly to that specific endpoint. We wouldn't consider these cases in our book.

When socket binding is delegated to the operating system, there is no guarantee that it will be bound to the same endpoint each time. Even if there is a single network interface and a single IP address on the host, the socket may be bound to a different protocol port number every time the implicit binding is performed.

Unlike client applications that usually don't care through which IP address and protocol port number its active socket will be communicating with the remote application, the server application usually needs to bind its acceptor socket to a particular endpoint explicitly. This is explained by the fact that the server's endpoint must be known to all the clients that want to communicate with it and should stay the same after the server application is restarted.

This recipe explains how to bind a socket to particular endpoint with Boost.Asio.

How to do it…

The following algorithm describes steps required to create an acceptor socket and to bind it to an endpoint designating all IP addresses available on the host and a particular protocol port number in the IPv4 TCP server application:

  1. Obtain the protocol port number on which the server should listen for incoming connection requests.
  2. Create an endpoint that represents all IP addresses available on the host and the protocol port number obtained in the step 1.
  3. Create and open an acceptor socket.
  4. Call the acceptor socket's bind() method, passing the endpoint object as an argument to it.

The following code sample demonstrates possible implementation of the algorithm. It is assumed that the protocol port number has already been obtained by the application:

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

using namespace boost;

int main()
{
  // Step 1. Here we assume that the server application has
  // already obtained the protocol port number.
  unsigned short port_num = 3333;

  // Step 2. Creating an endpoint.
  asio::ip::tcp::endpoint ep(asio::ip::address_v4::any(),
    port_num);

  // Used by 'acceptor' class constructor.
  asio::io_service ios;

  // Step 3. Creating and opening an acceptor socket.
  asio::ip::tcp::acceptor acceptor(ios, ep.protocol());

  boost::system::error_code ec;

  // Step 4. Binding the acceptor socket.
  acceptor.bind(ep, ec);

  // Handling errors if any.
  if (ec != 0) {
    // Failed to bind the acceptor socket. Breaking
    // execution.
    std::cout << "Failed to bind the acceptor socket."
      << "Error code = " << ec.value() << ". Message: "
      << ec.message();

    return ec.value();
  }

  return 0;
}

How it works…

We begin by obtaining a protocol port number in step 1. The process of obtaining this parameter is beyond the scope of this recipe; therefore, here we assume that the port number has already been obtained and is available at the beginning of the sample.

In step 2 we create an endpoint representing all IP addresses available on the host and the specified port number.

In step 3 we instantiate and open the acceptor socket. The endpoint we created in step 2 contains information about the transport protocol and the version of the underlying IP protocol (IPv4). Therefore, we don't need to create another object representing the protocol to pass it to the acceptor socket's constructor. Instead, we use the endpoint's protocol() method, which returns an object of the asio::ip::tcp class representing the corresponding protocols.

The binding is performed in step 4. This is quite a simple operation. We call the acceptor socket's bind() method, passing an object representing an endpoint to which the acceptor socket should be bound as an argument of the method. If the call succeeds, the acceptor socket is bound to the corresponding endpoint and is ready to start listening for incoming connection requests on that endpoint.

Tip

Downloading the example code

You can download the example code files from your account at http://www.packtpub.com for all the Packt Publishing books you have purchased. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

There's more…

UDP servers don't establish connections and use active sockets to wait for incoming requests. The process of binding an active socket is very similar to binding an acceptor socket. Here, we present a sample code demonstrating how to bind a UDP active socket to an endpoint designating all IP addresses available on the host and a particular protocol port number. The code is provided without explanation:

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

using namespace boost;

int main()
{
  // Step 1. Here we assume that the server application has
  // already obtained the protocol port number.
  unsigned short port_num = 3333;

  // Step 2. Creating an endpoint.
  asio::ip::udp::endpoint ep(asio::ip::address_v4::any(),
    port_num);

  // Used by 'socket' class constructor.
  asio::io_service ios;

  // Step 3. Creating and opening a socket.
  asio::ip::udp::socket sock(ios, ep.protocol());

  boost::system::error_code ec;

  // Step 4. Binding the socket to an endpoint.
  sock.bind(ep, ec);

  // Handling errors if any.
  if (ec != 0) {
    // Failed to bind the socket. Breaking execution.
    std::cout << "Failed to bind the socket."
      << "Error code = " << ec.value() << ". Message: "
      << ec.message();

    return ec.value();
  }

  return 0;
}

See also

  • The Creating an endpoint recipe provides more information on endpoints
  • The Creating an active socket recipe provides more details about the asio::io_service and asio::ip::tcp classes and demonstrates how to create and open an active socket
  • The Creating a passive socket recipe provides information about passive sockets and demonstrates how to create and open them
You have been reading a chapter from
Boost.Asio C++ Network Programming Cookbook
Published in: Jan 2016
Publisher:
ISBN-13: 9781783986545
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image