At the server side:
If the client is a child process of the server or vice versa, the sockets can be created using "socketpair" instead and the other connection establishment steps can be skipped. In this case the socket mechanism is more or less the same as a pipe - the main differences being that the communication over sockets is bidrectional, and that datagram style can be used.
Using the datagram style of communication between sockets on the same machine has some interesting implications very different to those when using pipes. Primarily the fact that data is sent and recieved in chunks (datagrams, packets); but also, and more interestingly, that the communication is unreliable in both delivery and ordering.
It might seem that an implementation would never drop packets destined for the same machine (and which, therefore, do not need to travel over a physical network), but in fact there are situations where this might actually make sense - for example when the receiver is not consuming packets as quickly as the sender is producing them. On the other hand, I can't think of a reason to deliver packets in a different order from which they are sent. Never-the-less it is probably best to assume that datagram communication is unreliable and unordered even when not communication over a network.
The real hint of this is the subsection called "interface naming" which briefly deals with the mechanisms available to discover the various interfaces in the system, and how they are named. By "interfaces" it's referring to the network interfaces, which often (but certainly not always) have a one-to-one correspondence with some piece of networking hardware (such as an ethernet card or modem).
(one exception to the rule about corresponding hardware is the "lo" interface, otherwise known as the loopback. The loopback has, as far as I know, no real function other than to allow binding a network socket when no other interface is available, which means it is of dubios value anyway.)
What's really missing from the manual is an explanation of why you would want to find the list of interfaces, and especially what you could do with it when you had it. The key thing that it fails to mention is that, on having gotten the name of some network interface, you can create a socket and then use ioctl calls on that socket in order to control or discover various aspects of the particular interface (such as the IP address).
One use would be, in systems/networking administration software, to enable the configuring of the interfaces, much as the "ifconfig" program does.
Another use is, on multi-homed systems (what's that?), to be able to bind to some address on a particular interface, rather than on all interfaces.
The structure struct ifreq is an undocumented structure defined in <net/inet.h>. It is used to pass info to and recieve info from the ioctl call. In truth it is not a well defined structure at all but rather an interface name followed by union of various types - as different types are applicable to the different ioctls.
So the structure for a particular ioctl resembles the following:
Note!!: Given that the interface name array ifr_name is defined to be of size IFNAMSIZ, then if the interface name is actually IFNAMSIZ in length, there will NOT be space to store the terminating nul character! This implies that you must check for this condition and treat it specially.
The ioctl numbers are defined in <sys/ioctl.h>. I won't go through them all here because it would take too much time, and besides I don't know what they all do myself. However, for many of them it should be reasonably easy to figure it out. I give an example below (SIOCGIFADDR - get interface address. Not that the equivalent "set interface address" is almost certainly SIOCSIFADDR).