You have probably heard about socket programming. Socket programming is the de facto way to write programs that communicate over a network. You can send and receive data from other applications or systems using sockets. In this blog post, we'll take a look at socket programming. We'll discuss what sockets are and how they work. By the end of this post, you'll have a better understanding of sockets. So let's get started!
Sockets are simply an endpoint for communication, similar to how we use ports on our phones for sending and receiving data across the network. They are used nearly everywhere, but as a technology, they often need to be understood.
Before we start, let's take a brief look at the short history of the socket.
- 1971. The term socket appeared in the publication of RPC 147 when it was used in the ARPANET.
- 1983. Most modern implementations of sockets are based on Berkeley sockets.
- 1989. UC Berkeley released versions of the network library free from the licensing constraints of AT&T copyright-protected Unix.
- 1991. Windows define its network API called WinSock.
There are several types of sockets, but only two appear to be useful. They are stream sockets and datagram sockets.
Stream sockets are reliable two-way connected communication streams. For instance, your web browsers use HTTP, which uses stream sockets to get pages. They are reliable because they use the Transmission Control Protocol (TCP) protocol. TCP makes sure data arrives sequentially and error-free.
Datagram sockets use the User Datagram Protocol (UDP). If you use datagram sockets to send data, it may or may not arrive. It may come out of order. If it arrives, though, the data within the packet will be error-free. Datagram sockets are typically used in a system where you can ignore the dropped packets—applications like games, audio, or video, for instance.
The socket was invented in Berkeley as part of the BSD flavor of Unix. And it has become the standard way to communicate over the internet. Today all machines, be it Windows, Linux, or Mac, support the so-called Berkeley Socket API.
The primary Berkeley socket API are:
socket()creates a new socket. An endpoint for communication and returns a file descriptor.
bind()associates a socket with an address, i.e., an IP address and a port number. Bind is typically used on the server side.
listen()is used on the server side and causes a bound TCP socket to be ready for incoming connections.
accept()is used on the server side. It creates a new socket for each connection and removes the connection from the listening queue.
connect()establishes a direct communication link to a specific remote host. It is used on the client side and assigns a free local port number to a socket.
recvfrom()are used for sending and receiving data.
close()causes the system to release resources allocated to a socket. In the case of TCP, the connection is terminated.
TCP Socket Flow
You will need more than simply knowing the socket abstraction above to help you with how to actually use it in coding. You need to know in what order to call the socket API. Let's take a look at the sequence of API calls and data flow for TCP:
For the server to be able to accept a connection, it needs to call
accept() consecutively. Once we've set up the server, the client calls
connect() to establish a connection to the server and initiate the three-way handshake. Socket uses
recv to exchange data between the client and server. When done, the client and server close their respective sockets.
In this post, we've taken a high-level look at what sockets are and how they work. We briefly covered the history of sockets and their place in computer networking. They start at Berkeley but become the standard of communication between systems over a network. In a future article, I will talk about socket programming in Python. Thanks for reading!