What is a Socket?

A socket can be thought of as an endpoint in a two-way communication channel. Socket routines create the communication channel, and the channel carries data between application programs either locally or over networks. Each socket open by a process — like any open file in a POSIX process — has a unique (within the process) number associated with it called a file descriptor, an integer that designates a socket and allows the application program to refer to it when needed.

Using an electrical analogy, you can think of the communication channel as the electrical wire with its plug and the port, or socket, as the electrical socket or outlet, as shown in Figure 1.
Figure 1. An Electrical Analogy Showing the Socket Concept
An Electrical Analogy Showing the Socket Concept

Figure 1 shows many application programs running on a client and many application programs on a server. When the client starts a socket call, a socket connection is made between an application on the client and an application on the server.

Another analogy used to describe socket communication is a telephone conversation. Dialing a phone number from your telephone is similar to starting a socket connection. The telephone switching unit knows where to logically make the correct switch to complete the call at the remote location. During your telephone conversation, this connection is present and information is exchanged. After you hang up, the connection is broken and you must start it again. The client uses the connect() function call to start the logical switch mechanism to connect to the server.

User processes ask the sockets library to create a socket when one is needed. The sockets library returns an integer, the file descriptor that the application uses every time it wants to refer to that socket.

Sockets perform in many respects like UNIX files or devices, so they can be used with such traditional operations as read() or write(). For example, after two application programs create sockets and open a connection between them, one program can use write() to send a stream of data, and the other can use read() to receive it. Because each file or socket has a unique descriptor, the system knows exactly where to send and to receive the data.