<arjen@andromeda.nl>
Mar 09, 2012
Document Information | |
---|---|
Version | 0.2 |
Organization | Andromeda Technology & Automation |
Abstract:
The network communication class library encapsulates the UNIX socket layer for network communication and provides standard io stream functionality.
The way processes communicate on the internet is through the use of -sockets-. The socket layer provides the interface between user processes and the network protocol stacks in the kernel of an operating system. A process can use a large variation of sockets, depending on the type of communication such as streams or datagrams or depending on the address familiy that is used like IPv6 or UNIX.
When two processes communicate through sockets, there is a socket on either side of the communication link. In other words, each process has its own socket while the underlying network stacks transfer the data from one socket to the other and vice versa. Which sockets take part in the communication is determined by the -host- and the -service- on which the socket resides. In many cases, the -service- also dictates the way the information is exchanged between the processes that hold the sockets.
In C++ standard iostream classes and objects exist to perform input and output operations on the controlling terminal of a process ('cin' and 'cout'), on files and device streams and on blocks of memory holding character strings. The socket stream classes provide this functionality for sockets in a way that is intended to be easy to use for the application programmer. Classes similar to the fstream and stringstream classes implement reading and writing data to and from sockets. At the highest level, an application is able to read data directly by specifying a URL, for example:
string page; link = isockstream("http://www.andromeda.nl/index.html"); link >> page;At a slightly lower level, an application program would open a stream which connects to a host or address and a specific service. On the other hand, a server application would create a listening socket on a socket address and a service. Such a socket waits for incoming connection requests and after accepting a connection, a new socket is created through which the actual communication takes place. The new socket can then be used in creating an iostream object. Note that there can never be data transfer through a listening socket.
A socket needs an address to listen on or to connect to. Depending on the address family used, a socket address has a different set of attributes, such as a pathname for UNIX local addresses or an IP address and port number for internet addresses. Also, diffrent kinds of addresses have different sets of operations defined on them.
Internally, sockets use numerical addresses and port numbers, whereas human users and programmers may prefer names for these entities. The conversion of such names into numbers and vice versa involves resolving through lookup systems such as DNS. A host is usually identifeid by its name and has one or more addresses, IPv4, IPv6 or other possible addresses. Although a host can have multiple addresses, a socket can connect to only one address. A service can have a similar problem. One service, as identified by name, may be available on multiple ports. It is in general up to an application to make appropriate selections in a multitude of addresses, although sensible defaults may be provided by address objects.
The following class diagram shows the classes and their relationships:
The top-level template classes are very similar to the standard iostream classes. The classes basic_sockstream, basic_isockstream, basic_osockstream and basic_sockbuf are almost the same as their basic_fstream, basic_ifstream, basic_ofstream and basic_filebuf counterparts. Just like the standard stream classes, these template classes use the character type and character traits as template parameters. Normal character and wide character variants are simply defined with typedefs, for example:
typedef basic_sockbuf<char> sockbuf; typedef basic_sockstream<char> sockstream;The key class in the hierarchy is the basic_sockbuf class that holds a close relation to the Socket class and performs the actual I/O operations. The sockbuf class inherits most of its functionality from the std::streambuf baseclass. The sockbuf overrides overflow() and underflow() members and provides the actual buffer space. Depending on the type of communication, two types of Socket objects are possible: Stream and Datagram.
The SocketAddress determines what a Socket connects to or listens to. For most Sockets, a SocketAddress basicly consists of a port and an IP address which are determined from the Service and Host for which the socket is intended. Only UNIX domain sockets are defined by a single pathname of the socket device. Depending on the address family that is used for the Socket Address, one of the three kinds of Socket Address is used to connect a socket: UNIX, IPv4 or IPv6. It is up to an application programmer to figure out where a Sockets connects to and create an appropriate type of SocketAddress to which a Socket can connect or listen.
Classes to help an application setup a Socket Address are Host and Service, which perform lookup functions as implemented in getaddrinfo(3).
Derived from the std::basic_iostream<>
template class.
Derived from the std::basic_istream<>
template class.
Derived from the std::basic_ostream<>
template class.
The basic_sockbuf<>
template class applies the functionality of
the std::basic_streambuf
to network sockets.
The sockbuf
class overrides a few streambuf
virtual functions
to implement input and output to the actual socket through a Socket
object.
sockbuf
to a Socket
object.
The Socket represents the device through which the actual communication takes place. This class encapsulates the socket interface in the UNIX or Linux kernel. A Socket is itself an abstract base class from which two types of Socket are derived: A StreamSocket and a DatagramSocket. Each of these classes have special properties and only the common parts are defined in the Socket base class. Note that the actual socket is not closed on destruction of a Socket object. The Close() method must be called to close the socket's file descriptor. As a result, it is safe for Socket objects to be copied, for example when passing such an object as a parameter or return value.
Implements a socket of the SOCK_STREAM type. Note that a StreamSocket object is either listening for incoming connection requests or is connected to a peer socket.
Implements a socket of the SOCK_DGRAM type.
The abstract base class for all kinds of socket addresses. The SocketAddress class provides an interface for binding and connecting sockets.
sockaddr
pointer that can be used by the bind(2)
or connect(2) system calls.
sockaddr
structure that can be used by the bind(2)
or connect(2) system calls.
Implementation of SocketAddress for UNIX domain sockets.
Implementation of SocketAddress for IPv4 domain sockets.
Implementation of SocketAddress for IPv6 domain sockets.
A Service is determined by its name, port number and service type (stream or datagram).
A Port is determined by its port number and socket type (stream, datagram, etcetera).
An InternetAddress object holds an IP address which can be either an IPv4 address or an IPv6 address. Its main purpose is to perform the conversion between addresses in network byte order end textual representations of an IP address.
struct addrinfo
as used by getaddrinfo(3),
struct in_addr
, struct in6_addr
and String
With the IP address in character string form, the address family is determined by the presence
of colon (:) characters in the IP address, as these can only occur in IPv6 addresses.
See also inet_pton(3)
struct in_addr
format.
struct in6_addr
format.