Unix domain socket

Last updated

In client-server computing, a Unix domain socket is a Berkeley socket that allows data to be exchanged between two processes executing 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.

Contents

Regardless of the range of communication (same host or different host), [2] Unix computer programs that perform socket communication 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 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. 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 file semaphore. No I/O occurs on this file when the client and server send messages to each other. [7]

History

Sockets first appeared in Berkeley Software Distribution 4.2 (1983). [8] It became a POSIX standard in 2000. [8] The application programming interface has been ported to virtually every Unix implementation and most other operating systems. [8]

Socket instantiation

Both the server and the client must instantiate a socket object by executing the socket() system call. Its usage is: [9]

intsocket(intdomain,inttype,intprotocol);

The domain parameter should be one of the following common ranges of communication: [10]

  1. Within the same host by using the constant AF_UNIX [lower-alpha 1]
  2. Between two hosts via the IPv4 protocol by using the constant AF_INET
  3. Between two hosts via the IPv6 protocol by using the constant AF_INET6
  4. Within the same host or between two hosts via the Stream Control Transmission Protocol by using the constant SOCK_SEQPACKET [11]

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.

  1. SOCK_STREAM will create a stream socket. A stream socket provides a reliable, bidirectional, and connection-oriented communication channel between two processes. Data are carried using the Transmission Control Protocol (TCP). [10]
  2. SOCK_DGRAM will create a datagram socket. [lower-alpha 2] 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]
  3. SOCK_RAW will create an Internet Protocol (IP) datagram socket. A Raw socket skips the TCP/UDP transport layer and sends the packets directly to the network layer. [15]

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] [lower-alpha 3] 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]

structsockaddr_un{sa_family_tsun_family;/* AF_UNIX */charsun_path[92];}

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 parameter declaration 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]

intlisten(intserver_socket_fd,intbacklog);

Snippet to listen:

if(listen(server_socket_fd,4096)==-1)assert(0);

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:

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){server_algorithmic_dialog(accept_socket_fd);}}#define BUFFER_SIZE 1024voidserver_algorithmic_dialog(intaccept_socket_fd){charinput_buffer[BUFFER_SIZE];charoutput_buffer[BUFFER_SIZE];read(accept_socket_fd,input_buffer,BUFFER_SIZE);if(strcasecmp(input_buffer,"hola")==0)strcpy(output_buffer,"Hola Mundo");elseif(strcasecmp(input_buffer,"ciao")==0)strcpy(output_buffer,"Ciao Mondo");elsestrcpy(output_buffer,"Hello World");write(accept_socket_fd,output_buffer,strlen(output_buffer)+1);}

Server close a connection

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]

Snippet to close 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){server_algorithmic_dialog(accept_socket_fd);close(accept_socket_fd);}}

Snippet to illustrate the end of a dialog:

#define BUFFER_SIZE 1024voidserver_algorithmic_dialog(intaccept_socket_fd){charbuffer[BUFFER_SIZE];intread_count;/* Omit algorithmic dialog */read_count=read(accept_socket_fd,buffer,BUFFER_SIZE);if(read_count<1)return;/* Omit algorithmic dialog */}

Client instantiate and connect to /path/filename

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

Related Research Articles

<span class="mw-page-title-main">Operating system</span> Software that manages computer hardware resources

An operating system (OS) is system software that manages computer hardware and software resources, and provides common services for computer programs.

A Berkeley (BSD) socket is an application programming interface (API) for Internet domain sockets and Unix domain sockets, used for inter-process communication (IPC). It is commonly implemented as a library of linkable modules. It originated with the 4.2BSD Unix operating system, which was released in 1983.

SOCKS is an Internet protocol that exchanges network packets between a client and server through a proxy server. SOCKS5 optionally provides authentication so only authorized users may access a server. Practically, a SOCKS server proxies TCP connections to an arbitrary IP address, and provides a means for UDP packets to be forwarded. A SOCKS server accepts incoming client connection on TCP port 1080, as defined in RFC 1928.

In computing, mmap(2) is a POSIX-compliant Unix system call that maps files or devices into memory. It is a method of memory-mapped file I/O. It implements demand paging because file contents are not immediately read from disk and initially use no physical RAM at all. The actual reads from disk are performed after a specific location is accessed, in a lazy manner. After the mapping is no longer needed, the pointers must be unmapped with munmap(2). Protection information—for example, marking mapped regions as executable—can be managed using mprotect(2), and special treatment can be enforced using madvise(2).

In Unix and Unix-like computer operating systems, a file descriptor is a process-unique identifier (handle) for a file or other input/output resource, such as a pipe or network socket.

<span class="mw-page-title-main">Pseudoterminal</span> Pair of pseudo-device endpoints

In some operating systems, including Unix-like systems, a pseudoterminal, pseudotty, or PTY is a pair of pseudo-device endpoints (files) which establish asynchronous, bidirectional communication (IPC) channel between two or more processes.

Secure Shell (SSH) is a protocol allowing secure remote login to a computer on a network using public-key cryptography. SSH client programs typically run for the duration of a remote login session and are configured to look for the user's private key in a file in the user's home directory. For added security, it is common to store the private key in an encrypted form, where the encryption key is computed from a passphrase that the user has memorized. Because typing the passphrase can be tedious, many users would prefer to enter it just once per local login session. The most secure place to store the unencrypted key is in program memory, and in Unix-like operating systems, memory is normally associated with a process. A normal SSH client process cannot be used to store the unencrypted key because SSH client processes only last the duration of a remote login session. Therefore, users run a program called ssh-agent that runs beyond the duration of a local login session, stores unencrypted keys in memory, and communicates with SSH clients using a Unix domain socket.

In C programming, the functions getaddrinfo and getnameinfo convert domain names, hostnames, and IP addresses between human-readable text representations and structured binary formats for the operating system's networking API. Both functions are contained in the POSIX standard application programming interface (API).

No Starch Press is an American publishing company, specializing in technical literature often geared towards the geek, hacker, and DIY subcultures. Popular titles include Hacking: The Art of Exploitation, Andrew Huang's Hacking the Xbox, and How Wikipedia Works.

In computing, ioctl is a system call for device-specific input/output operations and other operations which cannot be expressed by regular file semantics. It takes a parameter specifying a request code; the effect of a call depends completely on the request code. Request codes are often device-specific. For instance, a CD-ROM device driver which can instruct a physical device to eject a disc would provide an ioctl request code to do so. Device-independent request codes are sometimes used to give userspace access to kernel functions which are only used by core system software or still under development.

<span class="mw-page-title-main">Music on Console</span> Console audio player

Music On Console (MOC) is an ncurses-based console audio player for Linux/UNIX. It was originally written by Damian Pietras, and is currently maintained by John Fitzgerald. It is designed to be powerful and easy to use, with an interface inspired by the Midnight Commander console file manager. The default interface layout comprises a file list in the left pane with the playlist on the right. It is configurable with customizable key bindings, color schemes and interface layouts. MOC comes with several themes defined in text files, which can be modified to create new layouts. It supports ALSA, OSS or JACK outputs.

Netlink is a socket family used for inter-process communication (IPC) between both the kernel and userspace processes, and between different userspace processes, in a way similar to the Unix domain sockets available on certain Unix-like operating systems, including its original incarnation as a Linux kernel interface, as well as in the form of a later implementation on FreeBSD. Similarly to the Unix domain sockets, and unlike INET sockets, Netlink communication cannot traverse host boundaries. However, while the Unix domain sockets use the file system namespace, Netlink sockets are usually addressed by process identifiers (PIDs).

In computer science, the event loop is a programming construct or design pattern that waits for and dispatches events or messages in a program. The event loop works by making a request to some internal or external "event provider", then calls the relevant event handler.

A network socket is a software structure within a network node of a computer network that serves as an endpoint for sending and receiving data across the network. The structure and properties of a socket are defined by an application programming interface (API) for the networking architecture. Sockets are created only during the lifetime of a process of an application running in the node.

Transparent Inter Process Communication (TIPC) is an inter-process communication (IPC) service in Linux designed for cluster-wide operation. It is sometimes presented as Cluster Domain Sockets, in contrast to the well-known Unix Domain Socket service; the latter working only on a single kernel.

splice is a Linux-specific system call that moves data between a file descriptor and a pipe without a round trip to user space. The related system call vmsplice moves or copies data between a pipe and user space. Ideally, splice and vmsplice work by remapping pages and do not actually copy any data, which may improve I/O performance. As linear addresses do not necessarily correspond to contiguous physical addresses, this may not be possible in all cases and on all hardware combinations.

An NTFS reparse point is a type of NTFS file system object. It is available with the NTFS v3.0 found in Windows 2000 or later versions. Reparse points provide a way to extend the NTFS filesystem. A reparse point contains a reparse tag and data that are interpreted by a filesystem filter driver identified by the tag. Microsoft includes several default tags including NTFS symbolic links, directory junction points, volume mount points and Unix domain sockets. Also, reparse points are used as placeholders for files moved by Windows 2000's Remote Storage Hierarchical Storage System. They also can act as hard links, but are not limited to pointing to files on the same volume: they can point to directories on any local volume. The feature is inherited to ReFS.

select is a system call and application programming interface (API) in Unix-like and POSIX-compliant operating systems for examining the status of file descriptors of open input/output channels. The select system call is similar to the poll facility introduced in UNIX System V and later operating systems. However, with the c10k problem, both select and poll have been superseded by the likes of kqueue, epoll, /dev/poll and I/O completion ports.

<span class="mw-page-title-main">SocketCAN</span> Open source controller area network drivers and networking stack for the Linux kernel

SocketCAN is a set of open source CAN drivers and a networking stack contributed by Volkswagen Research to the Linux kernel. SocketCAN was formerly known as Low Level CAN Framework (LLCF).

<span class="mw-page-title-main">Michael Kerrisk</span>

Michael Kerrisk is a technical author, programmer and, since 2004, maintainer of the Linux man-pages project, succeeding Andries Brouwer. He was born in 1961 in New Zealand and lives in Munich, Germany.

References

  1. Kerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1149. ISBN   978-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.
  2. 1 2 3 Kerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1150. ISBN   978-1-59327-220-3.
  3. Kerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1150. ISBN   978-1-59327-220-3. The server binds its socket to a well-known address (name) so that clients can locate it.
  4. 1 2 Stevens, Richard W.; Fenner, Bill; Rudoff, Andrew M. (2004). Unix Network Programming (3rd ed.). Pearson Education. p. 14. ISBN   81-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.
  5. 1 2 Kerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1169. ISBN   978-1-59327-220-3.
  6. 1 2 3 4 Kerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1159. ISBN   978-1-59327-220-3.
  7. 1 2 Kerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1166. ISBN   978-1-59327-220-3.
  8. 1 2 3 Kerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1149. ISBN   978-1-59327-220-3.
  9. 1 2 Kerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1153. ISBN   978-1-59327-220-3.
  10. 1 2 3 Kerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1151. ISBN   978-1-59327-220-3.
  11. 1 2 "Linux Programmer's Manual (unix - sockets for local interprocess communication)". 30 April 2018. Retrieved 22 February 2019.
  12. Kerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1197. ISBN   978-1-59327-220-3.
  13. Kerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1183. ISBN   978-1-59327-220-3.
  14. Kerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1152. ISBN   978-1-59327-220-3.
  15. Kerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1184. ISBN   978-1-59327-220-3.
  16. 1 2 Kerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1181. ISBN   978-1-59327-220-3.
  17. 1 2 Kerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1165. ISBN   978-1-59327-220-3.
  18. Kerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1154. ISBN   978-1-59327-220-3.
  19. 1 2 3 "Linux manual page for listen()".
  20. Kerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1157. ISBN   978-1-59327-220-3.
  21. "Linux manual page for accept()".
  22. Kerrisk, Michael (2010). The Linux Programming Interface. No Starch Press. p. 1160. ISBN   978-1-59327-220-3.

Notes

  1. Alternatively, PF_UNIX or AF_LOCAL may be used. [11] The AF stands for "Address Family", and the PF stands for "Protocol Family".
  2. A datagram socket should not be confused with a datagram packet used in the network layer. [13]
  3. In UNIX, Everything is a file.