Mechanism for data exchange between processes executing on the same host
In client-server computing, a Unix domain socket is a Berkeley socket that allows data to be exchanged between two processesexecuting on the same Unix or Unix-like host computer.[1] This is similar to an Internet domain socket that allows data to be exchanged between two processes executing on different host computers.
Regardless of the range of communication (same host or different host),[2] Unix computer programs that perform socketcommunication are similar. The only range of communication difference is the method to convert a name to the address parameter needed to bind the socket's connection. For a Unix domain socket, the name is a /path/filename. For an Internet domain socket, the name is an IP address:Port number. In either case, the name is called an address.[3]
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.[4] Upon accepting a client connection, the server then executes a readsystem 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. The application's algorithm may entail multiple read/write interactions. Upon completion of the algorithm, the client executes exit()[5] and the server executes close().[6]
For a Unix domain socket, the socket's address is a /path/filename identifier. The server will create /path/filename on the filesystem to act as a lock filesemaphore. No I/O occurs on this file when the client and server send messages to each other.[7]
The Unix domain socket label is used when the domain parameter's value is AF_UNIX. The Internet domain socket label is used when the domain parameter's value is either AF_INET or AF_INET6.[12]
The type parameter should be one of two common socket types: stream or datagram.[10] A third socket type is available for experimental design: raw.
SOCK_DGRAM will create a datagram socket.[b] A Datagram socket does not guarantee reliability and is connectionless. As a result, the transmission is faster. Data are carried using the User Datagram Protocol (UDP).[14]
For a Unix domain socket, data (network packets) are passed between two connected processes via the transport layer — either TCP or UDP.[16] For an 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.[16]
The protocol parameter should be set to zero for stream and datagram sockets.[2] For raw sockets, the protocol parameter should be set to IPPROTO_RAW.[9]
socket() return value
socket_fd=socket(intdomain,inttype,intprotocol);
Like the regular-file open() system call, the socket() system call returns a file descriptor.[2][c] The return value's suffix _fd stands for file descriptor.
Server bind to /path/filename
After instantiating a new socket, the server binds the socket to an address. For a Unix domain socket, the address is a /path/filename.
Because the socket address may be either a /path/filename or an IP_address:Port_number, the socket application programming interface requires the address to first be set into a structure. For a Unix domain socket, the structure is:[17]
The _un suffix stands for unix. For an Internet domain socket, the suffix will be either _in or _in6. The sun_ prefix stands for socket unix.[17]
Computer program to create and bind a stream Unix domain socket:[7]
#include<stdlib.h>#include<string.h>#include<stdio.h>#include<unistd.h>#include<assert.h>#include<sys/socket.h>#include<sys/types.h>#include<sys/un.h>/* Should be 91 characters or less. Some Unix-like are slightly more. *//* Use /tmp directory for demonstration only. */char*socket_address="/tmp/mysocket.sock";voidmain(void){intserver_socket_fd;structsockaddr_unsockaddr_un={0};intreturn_value;server_socket_fd=socket(AF_UNIX,SOCK_STREAM,0);if(server_socket_fd==-1)assert(0);/* Remove (maybe) a prior run. */remove(socket_address);/* Construct the bind address structure. */sockaddr_un.sun_family=AF_UNIX;strcpy(sockaddr_un.sun_path,socket_address);return_value=bind(server_socket_fd,(structsockaddr*)&sockaddr_un,sizeof(structsockaddr_un));/* If socket_address exists on the filesystem, then bind will fail. */if(return_value==-1)assert(0);/* Listen and accept code omitted. */}
The second parameter for bind() is a pointer to struct sockaddr. However, the parameter passed to the function is the address of a struct sockaddr_un. struct sockaddr is a generic structure that is not used. It is defined in the formal parameterdeclaration for bind(). Because each range of communication has its own actual parameter, this generic structure was created as a cast placeholder.[18]
Server listen for a connection
After binding to an address, the server opens a listen channel to a port by executing listen(). Its usage is:[19]
For a Unix domain socket, listen() most likely will succeed and return 0. For an Internet domain socket, if the port is in use, listen() returns -1.[19]
The backlog parameter sets the queue size for pending connections.[20] The server may be busy when a client executes a connect() request. Connection requests up to this limit will succeed. If the backlog value passed in exceeds the default maximum, then the maximum value is used.[19]
Server accept a connection
After opening a listen channel, the server enters an infinite loop. Inside the loop is a system call to accept(), which puts itself to sleep.[4] The accept() system call will return a file descriptor when a client process executes connect().[21]
Snippet to accept a connection:
intaccept_socket_fd;while(1){accept_socket_fd=accept(server_socket_fd,NULL,NULL);if(accept_socket_fd==-1)assert(0);if(accept_socket_fd)>0)/* client is connected */}
Server I/O on a socket
When accept() returns a positive integer, the server engages in an algorithmic dialog with the client.
Stream socket input/output may execute the regular-file system calls of read() and write().[6] However, more control is available if a stream socket executes the socket-specific system calls of send() and recv(). Alternatively, datagram socket input/output should execute the socket-specific system calls of sendto() and recvfrom().[22]
For a basic stream socket, the server receives data with read( accept_socket_fd ) and sends data with write( accept_socket_fd ).
Snippet to illustrate I/O on a basic stream socket:
The algorithmic dialog ends when either the algorithm concludes or read( accept_socket_fd ) returns < 1.[6] To close the connection, execute the close() system call:[6]
Computer program for the client to instantiate and connect a socket:[5]
#include<stdlib.h>#include<string.h>#include<stdio.h>#include<unistd.h>#include<assert.h>#include<sys/socket.h>#include<sys/types.h>#include<sys/un.h>/* Must match the server's socket_address. */char*socket_address="/tmp/mysocket.sock";voidmain(void){intclient_socket_fd;structsockaddr_unsockaddr_un={0};intreturn_value;client_socket_fd=socket(AF_UNIX,SOCK_STREAM,0);if(client_socket_fd==-1)assert(0);/* Construct the client address structure. */sockaddr_un.sun_family=AF_UNIX;strcpy(sockaddr_un.sun_path,socket_address);return_value=connect(client_socket_fd,(structsockaddr*)&sockaddr_un,sizeof(structsockaddr_un));/* If socket_address doesn't exist on the filesystem, *//* or if the server's connection-request queue is full, *//* then connect() will fail. */if(return_value==-1)assert(0);/* close( client_socket_fd ); <-- optional */exit(EXIT_SUCCESS);}
Client I/O on a socket
If connect() returns zero, the client can engage in an algorithmic dialog with the server. The client may send stream data via write( client_socket_fd ) and may receive stream data via read( client_socket_fd ).
Snippet to illustrate client I/O on a stream socket:
{/* Omit construction code */return_value=connect(client_socket_fd,(structsockaddr*)&sockaddr_un,sizeof(structsockaddr_un));if(return_value==-1)assert(0);if(return_value==0){client_algorithmic_dialog(client_socket_fd);}/* close( client_socket_fd ); <-- optional *//* When the client process terminates, *//* if the server attempts to read(), *//* then read_count will be either 0 or -1. *//* This is a message for the server *//* to execute close(). */exit(EXIT_SUCCESS);}#define BUFFER_SIZE 1024voidclient_algorithmic_dialog(intclient_socket_fd){charbuffer[BUFFER_SIZE];intread_count;strcpy(buffer,"hola");write(client_socket_fd,buffer,strlen(buffer)+1);read_count=read(client_socket_fd,buffer,BUFFER_SIZE);if(read_count>0)puts(buffer);}
See also
Pipeline (Unix) – Mechanism for inter-process communication using message passing
Netlink – Linux kernel interface for inter-process communication between processes
References
^Kerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1149. ISBN978-1-59327-220-3. Sockets are a method of IPC that allow data to be exchanged between applications, either on the same host (computer) or on different hosts connected by a network.
^ abcKerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1150. ISBN978-1-59327-220-3.
^Kerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1150. ISBN978-1-59327-220-3. The server binds its socket to a well-known address (name) so that clients can locate it.
^ abStevens, Richard W.; Fenner, Bill; Rudoff, Andrew M. (2004). Unix Network Programming (3rd ed.). Pearson Education. p. 14. ISBN81-297-0710-1. Normally, the server process is put to sleep in the call to accept, waiting for a client connection to arrive and be accepted.
^ abKerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1169. ISBN978-1-59327-220-3.
^ abcdKerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1159. ISBN978-1-59327-220-3.
^ abKerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1166. ISBN978-1-59327-220-3.
^ abcKerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1149. ISBN978-1-59327-220-3.
^ abKerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1153. ISBN978-1-59327-220-3.
^ abcKerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1151. ISBN978-1-59327-220-3.