Linux / Unix - Sockets
Unix Domain Sockets vs Internet Domain Sockets
- Unix Domain Sockets: a.k.a. IPC sockets, allow communication between 2 processes, i.e. the server and the client, on the same machine.
- use the file system as the address space (everything in Unix is a file) e.g.
/var/run/docker/containerd/containerd.sock
- use the file system as the address space (everything in Unix is a file) e.g.
- Internet Domain Sockets: allow communication over a network, i.e. the server and the client are on different machines.
- use the IP address and a port number as socket address, e.g.
10.20.30.40:4444;
- use the IP address and a port number as socket address, e.g.
As you can see from the system call below, they are distinguished by the domain.
Communication
Two processes may communicate with each other if each obtains a socket.
- The server process binds its socket to an address, opens a listen channel, and then continuously loops.
- Inside the loop, the server process is put to sleep while waiting to accept a client connection.
- Upon accepting a client connection, the server then executes a read system call that will block wait.
- The client connects to the server's socket via the server's address.
- The client process then writes a message for the server process to read.
At different levels:
- Unix domain socket: data packets are passed between two connected processes via the transport layer — either TCP or UDP.
- Internet domain socket: data are passed between two connected processes via the transport layer and the Internet Protocol (IP) of the network layer — either TCP/IP or UDP/IP.
System Calls
int socket(int domain, int type, int protocol);
Most important domains:
AF_INET: IPv4AF_INET6: IPv6AF_UNIX/AF_LOCAL: Unix Socket
Most common types:
SOCK_STREAM: a stream-oriented socket (TCP)SOCK_DGRAM: a datagram-oriented socket (UDP)
protocol: specify the protocol. In most cases there's only one protocol for the specified type, use 0 for protocol.
Example:
fd = socket(AF_UNIX, SOCK_STREAM, 0);
After we create the sockets on both server and client sides:
- Server side:
- use
bind()system call to bind it to an address. - use
listen()system call to mark the socket as passive. (by default, the socket is active) - use
accept()system call to accept an incoming connection.
- use
- Client side:
- use
connect()system call to connect to a passive socket, using the same address.
- use
Then use read() and write() system calls to communicate with the peer socket.
Remember to call close() to close the sockets.
Commands
Read more: Shell Cheatsheet - Networking