English
In order to reach a peer, a process must know its :term:`address`. An address is a value that identifies a peer in a given network. There exists many different kinds of address families. For example, some of them allow reaching a peer using the file system on the computer. Some others enable communicating with a remote peer through a network. The socket API provides generic functions: the peer address is taken as a ``struct sockaddr *``, which can point to any family of address. This is partly why sockets are a powerful abstraction.
In the following example, a C program is sending the bytes ``'h'``, ``'e'``, ``'l'``, ``'l'`` and ``'o'`` to a remote process located at address ``peer_addr``, using the already created socket ``sock``.
Message format
Networked applications were usually implemented by using the :term:`socket` :term:`API`. This API was designed when TCP/IP was first implemented in the `Unix BSD`_ operating system [Sechrest]_ [LFJLMT]_, and has served as the model for many APIs between applications and the networking stack in an operating system. Although the socket API is very popular, other APIs have also been developed. For example, the STREAMS API has been added to several Unix System V variants [Rago1993]_. The socket API is supported by most programming languages and several textbooks have been devoted to it. Users of the C language can consult [DC2009]_, [Stevens1998]_, [SFR2004]_ or [Kerrisk2010]_. The Java implementation of the socket API is described in [CD2008]_ and in the `Java tutorial <http://java.sun.com/docs/books/tutorial/networking/sockets/index.html>`_. In this section, we will use the C socket API to illustrate the key concepts.
Note that we can reuse our ``send_hello_to_peer`` function without any modification as we wrote it to handle any kind of sockets, including sockets using the IPv6 network protocol.
Now that we created an IPv6 socket, we can use it to reach another program if we know its IPv6 address. IPv6 addresses have a human-readable format that can be represented as a string of characters. The details of IPv6 addresses are out of scope of this section but here are some examples :
Now, we have built everything we need to send a message to the remote program. The ``create_socket_and_send_message`` function below assembles all the building blocks we created until now in order to send the message ``"hello"`` to the program running on port ``55555`` on the computer identified by the ``::1`` IPv6 address.
Operating systems allow assigning an address to a socket using the ``bind`` system call. This is useful when you want to receive messages from another program to which you announced your socket address. Once the address is assigned to the socket, the program can receive data from others using system calls such as ``recv`` and ``read``. Note that we can use the ``read`` system call as the operating system provides a socket as a file descriptor.
Operating systems enable linking a socket to a remote address so that every information sent through the socket will only be sent to this remote address, and the socket will only receive messages sent by this remote address. This can be done using the ``connect`` system call shown below.
Popular operating systems allow isolating different programs by executing them in separate `processes`. A :term:`socket` is a tool provided by the operating system that enables two separated processes to communicate with each other. A socket takes the form of a file descriptor and can be seen as a communication pipe through which the communicating processes can exchange arbitrary information. In order to receive a message, a process must be attached to a specific :term:`address` that the peer can use to reach it.
Receiving data from a peer using a socket
Sending a message to a remote peer using its IPv6 address
Sending data to a peer using a socket
send the least significant byte followed by the most significant byte
send the most significant byte followed by the least significant byte
The ``::1`` IPv6 address identifies the computer on which the current program is running.
The ``2001:6a8:308f:9:0:82ff:fe68:e520`` IPv6 address identifies the computer serving the ``https://beta.computer-networking.info`` website.
The `DATA` primitives are exchanged through a service access point. In the socket API, the equivalent to the service access point is the `socket`. A `socket` is a data structure which is maintained by the networking stack and is used by the application every time it needs to send or receive data through the networking stack.
The ``domain`` parameter specifies the address family that we will use to concretely perform the communication. For an IPv6 socket, the ``domain`` parameter will be set to the value ``AF_INET6``, telling the operating system that we plan to communicate using IPv6 addresses. The ``type`` parameter specifies the communication guarantees that we need. For now, we will use the type ``SOCK_DGRAM`` which allows us to send *unreliable messages*. This means that each data that we send at each call of ``sendto`` will either be completely received or not received at all. The last parameter will be set to ``0``. The following line creates a socket, telling the operating system that we want to communicate using IPv6 addresses and that we want to send unreliable messages.
The first argument is the file descriptor of the socket that we use to perform the communication. ``buf`` is a buffer of length ``len`` containing the bytes to send to the peer. The usage of ``flags`` argument is out of the scope of this section and can be set to 0. ``dest_addr`` is the socket address of the destination to which we want to send the bytes, its length is passed using the ``addrlen`` argument.