3

From APUE:

17.3 Unique Connections

A server can arrange for unique UNIX domain connections to clients using the standard bind, listen, and accept functions. Clients use connect to contact the server; after the connect request is accepted by the server, a unique connection exists between the client and the server. This style of operation is the same that we illustrated with Internet domain sockets in Figures 16.16 and 16.17.

If I am correct, there can be at most one connection between two internet domain TCP sockets.

How many connections can there be between two Unix domain sockets?

If there is also at most one, why does the book dedicate a section for making connection between two unix domain sockets unique?

Thanks.

Tim
  • 101,790

2 Answers2

6

I'm not convinced I like Steffen Ullrich's wording on that topic. Sockets are naturally complex because they are a generalized interface which can be used for a number of very different protocols (See note 1).

To generalize between different protocols, the sockets interface identifies common features of different protocols:

  • All protocols must have some address mechanism. (See note 1)
  • All data is sent from an address to an address.
  • Two types of protocol are useful to discuss here:
    • Some protocols represent a connection: SOCK_STREAM
    • Some protocols represent a series of messages: SOCK_DGRAM

SOCK_STREAM protocols are generally very different from SOCK_DGRAM protocols. But within each of these groups, protocols don't differ so much.

SOCK_STREAM

  • Example: TCP
  • Data arrives in a long stream without any breaks.
  • Data always arrives in the order it was sent

Connection orientated protocols are always(?) a pair of sockets with data sent between them in a single connection. Connection protocols usually support some form of "listening" socket as well, who's sole purpose is to wait for new connection requests.

Think of connection orientated sockets as two telephones with a line between them.

Calling connect() and accept() results in a new connection with two bound sockets (one on each side of the connection).

SOCK_DGRAM

  • Example UDP
  • Data arrives in the same blocks (messages) it was sent, not mashed into a continuous stream
  • Messages might not arrive in order.

Datagram orientated protocols are very different. Sockets can be configured to act a little like mail boxes, receiving messages from anywhere. There's no requirement to have a connection. In the case of UDP, any packet sent to the right IP and port from any IP and port will be picked up by the same socket. So you can hold conversations with several different computers through the same socket.

There is a special meaning for connect() on SOCK_DGRAM sockets.

If the socket sockfd is of type SOCK_DGRAM, then addr is the address to which datagrams are sent by default, and the only address from which datagrams are received.

This does not create a new unique connection. It just limits which messages will be received by this one socket and NOT the socket on the other side.

The sendto() function allows the program to send a message and specify an address to send it.

Unix domain sockets

These come in both flavors (SOCK_STREAM and SOCK_DGRAM) just as internet sockets do (TCP and UDP). So for SOCK_STREAM unix sockets, yes they just have one connection between a pair of sockets. But SOCK_DGRAM unix sockets are different (just as UDP is different from TCP).


Note 1: Unix sockets are funky because there is no underlying protocol as such, they are a construct of the kernel. The kernel is free to use it's own socket inodes as the addresses mechanism. As mosvy points out this can lead to odd behaviour when you try to determine the address of a unix socket.

  • unix sockets come in 3 "flavors", not 2, and the one you omit is the most useful, because it preserves message boundaries (like dgram), and it allows multiplexing connections (like stream). 2. unix sockets do not always have an address 3. a listening socket and the multiplexing with accept() is purely an API thing; no wi
  • –  Mar 04 '19 at 09:09
  • Two types of protocol are useful to discuss here: Didn't say there were only2. 2) Yes they do. You must have an identifier for the end point. I read somewhere that unix sockets use inodes as addresses. Hunting for a reference. 3) A listening socket is implied by the protocols such as TCP (It's not just API). There must be something waiting for the initial SYN packet, ready to send an ACK packet and receive the final SYNACK packet before the new socket (connection) is open.
  • – Philip Couling Mar 04 '19 at 09:26
  • No, unix sockets that were only connect()ed or those created with socketpair() do not have an address in any shape or form. I won't annoy you with more stuff, since I'm not sure if it is of any use. –  Mar 04 '19 at 09:28
  • The inode referenced by any open file description (including inet sockets) has nothing to do with the address a socket is bound to (which in the case of a non-abstract unix domain is actually a different device:inode pair -- the thing that is obtained via SOCK_DIAG/UNIX_DIAG_VFS by tools like ss). But let's cut it here, mkay? Instead of telling me that I'm wrong you could've just called getpeername() and getsockname() on any of the socket returned by socketpair(). –  Mar 04 '19 at 09:54
  • I didn't find anything offensive, but I don't have any intention to continue this discussion, since apparently I'm not able to help you. –  Mar 04 '19 at 10:20
  • @mosvy I've made a minor edit to try to reduce the contention. Feel free to review whether this fixes your concern. Precise accuracy risks damaging clarity, clarity risk damaging accuracy and thus brevity takes time. – Philip Couling Mar 04 '19 at 11:05