#### TCP, UDP and ICMP

Asio provides off-the-shelf support for the internet protocols TCP, UDP and ICMP.

###### TCP Clients

Hostname resolution is performed using a resolver, where host and service names are looked up and converted into one or more endpoints:

    ip::tcp::resolver resolver(my_io_context);
    ip::tcp::resolver::query query("www.boost.org", "http");
    ip::tcp::resolver::iterator iter = resolver.resolve(query);
    ip::tcp::resolver::iterator end; // End marker.
    while (iter != end)
    {
      ip::tcp::endpoint endpoint = *iter++;
      std::cout << endpoint << std::endl;
    }

The list of endpoints obtained above could contain both IPv4 and IPv6 endpoints, so a program should try each of them until it finds one that works. This keeps the client program independent of a specific IP version.

To simplify the development of protocol-independent programs, TCP clients may establish connections using the free functions connect() and async_connect(). These operations try each endpoint in a list until the socket is successfully connected. For example, a single call:

    ip::tcp::socket socket(my_io_context);
    asio::connect(socket, resolver.resolve(query));

will synchronously try all endpoints until one is successfully connected. Similarly, an asynchronous connect may be performed by writing:

    asio::async_connect(socket_, iter,
        boost::bind(&client::handle_connect, this,
          asio::placeholders::error));

    // ...

    void handle_connect(const error_code& error)
    {
      if (!error)
      {
        // Start read or write operations.
      }
      else
      {
        // Handle error.
      }
    }

When a specific endpoint is available, a socket can be created and connected:

    ip::tcp::socket socket(my_io_context);
    socket.connect(endpoint);

Data may be read from or written to a connected TCP socket using the receive(), async_receive(), send() or async_send() member functions. However, as these could result in short writes or reads, an application will typically use the following operations instead: read(), async_read(), write() and async_write().

###### TCP Servers

A program uses an acceptor to accept incoming TCP connections:

    ip::tcp::acceptor acceptor(my_io_context, my_endpoint);
    ...
    ip::tcp::socket socket(my_io_context);
    acceptor.accept(socket);

After a socket has been successfully accepted, it may be read from or written to as illustrated for TCP clients above.

###### UDP

UDP hostname resolution is also performed using a resolver:

    ip::udp::resolver resolver(my_io_context);
    ip::udp::resolver::query query("localhost", "daytime");
    ip::udp::resolver::iterator iter = resolver.resolve(query);
    ...

A UDP socket is typically bound to a local endpoint. The following code will create an IP version 4 UDP socket and bind it to the "any" address on port `12345`:

    ip::udp::endpoint endpoint(ip::udp::v4(), 12345);
    ip::udp::socket socket(my_io_context, endpoint);

Data may be read from or written to an unconnected UDP socket using the receive_from(), async_receive_from(), send_to() or async_send_to() member functions. For a connected UDP socket, use the receive(), async_receive(), send() or async_send() member functions.

###### ICMP

As with TCP and UDP, ICMP hostname resolution is performed using a resolver:

    ip::icmp::resolver resolver(my_io_context);
    ip::icmp::resolver::query query("localhost", "");
    ip::icmp::resolver::iterator iter = resolver.resolve(query);
    ...

An ICMP socket may be bound to a local endpoint. The following code will create an IP version 6 ICMP socket and bind it to the "any" address:

    ip::icmp::endpoint endpoint(ip::icmp::v6(), 0);
    ip::icmp::socket socket(my_io_context, endpoint);

The port number is not used for ICMP.

Data may be read from or written to an unconnected ICMP socket using the receive_from(), async_receive_from(), send_to() or async_send_to() member functions.

###### See Also

ip::tcp, ip::udp, ip::icmp, daytime protocol tutorials, ICMP ping example.