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 domain
s:
AF_INET
: IPv4AF_INET6
: IPv6AF_UNIX
/AF_LOCAL
: Unix Socket
Most common type
s:
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