Sockets provide point-to-point, two-way communication
between two processes. Sockets are very versatile and are a basic component of interprocess
and intersystem communication. A socket is an endpoint of communication to which a name can
be bound. It has a type and one or more associated processes.

Sockets
exist in communication domains. A socket domain is an abstraction that provides an addressing
structure and a set of protocols. Sockets connect only with sockets in the same domain.
Twenty three socket domains are identified (see <sys/socket.h>), of which only the
UNIX and Internet domains are normally used Solaris 2.x Sockets can be used to communicate
between processes on a single system, like other forms of IPC.

The UNIX domain
provides a socket address space on a single system. UNIX domain sockets are named with UNIX
paths. Sockets can also be used to communicate between processes on different systems. The
socket address space between connected systems is called the Internet domain.

Socket
types define the communication properties visible to the application. Processes communicate
only between sockets of the same type. There are five types of socket.

A stream socket

--
provides two-way, sequenced, reliable, and unduplicated flow of data with no record
boundaries. A stream operates much like a telephone conversation. The socket type is
SOCK_STREAM, which, in the Internet domain, uses Transmission Control Protocol (TCP).

A
datagram socket

-- supports a two-way flow of messages. A on a datagram socket may receive
messages in a different order from the sequence in which the messages were sent. Record
boundaries in the data are preserved. Datagram sockets operate much like passing letters back
and forth in the mail. The socket type is SOCK_DGRAM, which, in the Internet domain,
uses User Datagram Protocol (UDP).

A sequential packet socket

-- provides a two-way, sequenced,
reliable, connection, for datagrams of a fixed maximum length. The socket type is
SOCK_SEQPACKET. No protocol for this type has been implemented for any protocol
family.

A
raw socket

provides access to the underlying communication protocols.

These sockets are
usually datagram oriented, but their exact characteristics depend on the interface provided
by the protocol.

int socket(int domain, int type, int protocol) is called to create a socket in the
specified domain and of the specified type. If a protocol is not specified, the system
defaults to a protocol that supports the specified socket type. The socket handle (a
descriptor) is returned. A remote process has no way to identify a socket until an address is
bound to it. Communicating processes connect through addresses. In the UNIX domain, a
connection is usually composed of one or two path names. In the Internet domain, a connection
is composed of local and remote addresses and local and remote ports. In most domains,
connections must be unique.

int bind(int s, const struct sockaddr *name, int namelen) is called to bind a path or
internet address to a socket. There are three different ways to call bind(), depending
on the domain of the socket.

For UNIX domain sockets with paths containing 14, or fewer characters, you can:

Connecting sockets is usually not symmetric. One process
usually acts as a server and the other process is the client. The server binds its socket to
a previously agreed path or address. It then blocks on the socket. For a SOCK_STREAM
socket, the server calls int listen(int s, int backlog) , which specifies how many
connection requests can be queued. A client initiates a connection to the server's socket by
a call to int connect(int s, struct sockaddr *name, int namelen) . A UNIX domain call
is like this:

If the client's
socket is unbound at the time of the connect call, the system automatically selects and binds
a name to the socket. For a SOCK_STREAM socket, the server calls accept(3N) to complete
the connection.

int accept(int s, struct sockaddr *addr, int *addrlen) returns a new socket descriptor
which is valid only for the particular connection. A server can have multiple
SOCK_STREAM connections active at one time.

Several functions to send
and receive data from a SOCK_STREAM socket. These are write(), read(), int
send(int s, const char *msg, int len, int flags), and int recv(int s, char *buf, int
len, int flags). send() and recv() are very similar to read() and
write(), but have some additional operational flags.

The flags parameter is formed from the bitwise OR of zero or
more of the following:

MSG_OOB

-- Send "out-of-band" data on sockets that
support this notion. The underlying protocol must also support
"out-of-band"
data. Only SOCK_STREAM sockets created
in the AF_INET address family support
out-of-band data.

MSG_DONTROUTE

-- The SO_DONTROUTE option is turned on for
the duration of the operation. It is
used only by diagnostic or routing pro-
grams.

MSG_PEEK

-- "Peek" at the data present on the socket; the data
is returned, but not consumed, so that a subsequent receive operation will see the same
data.

A datagram socket does not require that a connection be
established. Each message carries the destination address. If a particular local address is
needed, a call to bind() must precede any data transfer. Data is sent through calls to
sendto() or sendmsg(). The sendto() call is like a send() call
with the destination address also specified. To receive datagram socket messages, call
recvfrom() or recvmsg(). While recv() requires one buffer for
the arriving data, recvfrom() requires two buffers, one for the incoming message and
another to receive the source address.

Datagram sockets can also use connect() to connect
the socket to a specified destination socket. When this is done, send() and
recv() are used to send and receive data.

Sockets have a number of options that can be fetched with
getsockopt() and set with setsockopt(). These functions can be used at the native
socket level (level = SOL_SOCKET), in which case the socket option name must be
specified. To manipulate options at any other level the protocol number of the desired
protocol controlling the option of interest must be specified (see getprotoent() in
getprotobyname()).