Sockets are communication endpoints that enable interprocess message exchanging in a generic system. There are several operations available to control the lifecycle of a socket, for example: open, bind, send, receive, shutdown, and close.
In this article, we will take a look at the differences between shutdown and close while understanding how each operation works.
2. A Brief Review of Sockets
Sockets are networking software tailored to provide communication among processes. At present, the core network mostly structures over the TCP/IP model. In this context, a socket is typically called a network socket or Internet socket. We highlight that processes communicating over sockets can execute in the same machine (local system) or different machines (distributed system).
A socket is at the application layer taking into the TCP/IP model. Relatively, in the OSI Model, a socket locates at the session layer (layer 5). At last, three categories can define a network socket:
- Datagram: Sockets that use the User Datagram Protocol (UDP) to communicate processes without any connection. In such a way, datagram sockets guarantee neither reliability neither order in the interprocess message exchanging
- Stream: Sockets that employ the Transmission Control Protocol (TCP) to enable connection-oriented communications. Thus, stream sockets provide a sequential and error-free message exchanging between different processes
- Raw: Sockets that directly receive IP packets regardless of their transmission layer protocol. Typically, reading from a raw socket returns packets with their headers explicit. Similarly, raw sockets require packets with explicit headers to send them properly
3. Sockets in Action
We can say that opening a socket, in practice, means creating a file descriptor that enables full-duplex interprocess communication. Thus, processes communicating through a socket read the file descriptor to receive packets. In the same way, these processes write the file descriptor to send packets:
We should note that, at some point, the communication between processes may end.
Two operations are available to terminate this communication: shutdown and close. However, these operations can be used in particular ways to achieve different results. Next, we will learn the particularities of each one of these operations.
The shutdown operation represents a way to block the communication of a socket without destroying it. But, besides calling a socket shutdown, it is necessary to define how this operation will act. To do that, three execution modes are available: SHUT_RD, SHUT_WR, and SHUT_RDWR. These execution modes are described next.
The SHUT_RD mode blocks the socket from further receiving messages. So, pending data included in the socket’s buffer (i.e., not delivered) is still readable by the process that uses it. But, after reading the pending data, new attempts to read the socket will exclusively return zero-sized messages. Finally, we highlight that the execution of a shutdown SHUT_RD operation does not disable the sending function of a socket
The SHUT_WR mode prevents the socket from sending messages. Generally, the socket completes all pending requests to send messages done before a shutdown SHUT_WR operation. Furthermore, as part of the shutdown SHUT_WR execution, the socket informs connected clients (if there are any) that sending messages is suspended. At last, the shutdown SHUT_WR operation does not block the socket for receiving messages
The SHUT_RDWR mode blocks the socket from both sending and receiving messages. Similar to the other shutdown modes, the shutdown SHUT_RDWR operation does not destroy the socket. Thus, for example, a connection of a stream socket is not terminated. But, messages involved in sending and receiving operations do not reach their destination. This operation mode has a comparable result to executing both SHUT_RD and SHUT_WR shutdown operations sequentially
The image below summarizes the behavior of the shutdown operation according to its execution modes:
The close operation blocks the communication of a socket and destroys it. In other words, closing a socket represents terminating its connections (if there are any) and then close the file descriptor that enables the message exchanging. In this way, after executing a close operation, the process can neither read either write the socket. Thus, any attempt to operate on a closed socket will raise an exception to the process:
In this article, we reviewed the main concepts of sockets and recalled their operational behavior. Next, we studied the shutdown and close operations applied to sockets.
We can conclude that, albeit having similar characteristics, the execution of a shutdown operation does not destroy a socket; instead, it just limits its communication capacities according to the operation mode. Executing a closing operation, in turn, ends the connections of a socket (if any), and also closes its file descriptor, finally destroying the socket.