Inter-process communication using Socket: (connection-oriented communication in UNIX domain)
In addition to communication between different hosts on the network, the socket can also implement communication between different processes on the same host, and the communication established is bidirectional communication.
Man UNIX contains the following content:
Name)
UNIX, pf_unix, af_unix, pf_local, af_local? Intercept used for communication between local internal processes.
Synopsis (Overview)
# Include <sys/socket. h>
# Include <sys/UN. h>
Unix_socket = socket (pf_unix, type, 0 );
Error = socketpair (pf_unix, type, 0, int * Sv );
Description)
Pf_unix (also known as pf_local) socket family is used to provide effective inter-process communication on the same machine. UNIX sockets can be anonymous (created by socketpair (2) or associated with socket files. linux also supports an abstract namespace, which is independent of the file system.
Valid types include: sock_stream is used for stream-oriented sockets, and sock_dgram is used for datagram-oriented sockets, which can save message boundaries. UNIX sockets are always reliable and do not restructure the datagram.
UNIX socket supports transferring the file descriptor or process credit certificate to other processes as auxiliary data of the datagram.
Address format)
The UNIX address is defined as a file name in the file system or an individual string in the abstract namespace. the socket created by socketpair (2) is anonymous. for non-Anonymous sockets, the target address can be set using connect (2. you can use bind (2) to set the local address. when the socket is connected and does not have a local address, a unique address is automatically generated in the abstract namespace.
# Define unix_path_max 108
Struct sockaddr_un {
Sa_family_t sun_family;/* af_unix */
Char sun_path [unix_path_max];/* path */
};
Sun_family always contains af_unix. sun_path contains the path name of a socket with a null end in the file system. if sun_path starts with null and zero bytes, it points to the abstract namespace maintained by the Unix protocol module. the address of this socket in this namespace is given by the remaining bytes in sun_path. note that the name of the abstract namespace is not null and terminated.
Socket options)
Based on historical origins, these socket options are determined by the sol_socket type, even if they are specified by pf_unix. they can be set by setsockopt (2. use getsockopt (2) to read data from the socket family by specifying sol_socket.
So_passcred indicates the credit certificate that can be sent to receive process-assisted information. when this option is set and the socket is not connected, a unique name of the abstract namespace is automatically generated. the value is a Boolean integer.
Ancillary messages (Auxiliary Information)
These secondary information types are determined by the sol_socket type, even if they are specified by pf_unix. to send them, you can set the cmsg_level field of the cmsghdr structure to sol_socket and set the cmsg_type field to its type. for more information, see cmsg (3 ).
Scm_rights
Sends or receives a set of open file descriptors for other processes. The data part contains an integer array of file descriptors. The effects of uploaded file descriptors are the same as they have been created by DUP (2.
Scm_credentials
Send or receive UNIX credit certificates. certificates can be used for authentication. The delivery of credit certificates is transmitted in the form of struct ucred auxiliary information.
Struct ucred {
Pid_t PID;/* ID of the sender process */
Uid_t uid;/* User ID of the sending process */
Gid_t GID;/* Group ID of the sender process */
};
The credit certificate determined by the sender is checked by the kernel. A process with valid user ID 0 allows you to specify a value that does not match its own value. the sender must identify its own process (unless it has cap_sys_admin), its user ID, valid user ID, or set the user ID (unless it has cap_setuid ), and its group ID, valid group ID, or set group ID (unless it carries cap_setgid ). to receive a struct ucred message, you must activate the so_passcred option on the socket.
Errors (error)
Enomem
Memory overflow.
Econnrefused
Connect (2) calls a socket object that is not being monitored. This may occur when the remote connection does not exist or the file name is not a socket.
Einval
Invalid parameters are passed. The common cause is that the af_unix setting of the passed sun_type segment is lost, or the socket operation on the application is invalid.
Eopnotsupp
A stream operation is called on a non-stream-oriented socket, or an out-of-bounds data option is attempted.
Eprotonosupport
The passed protocol is not pf_unix.
Esocktnosupport
Unknown socket type.
Eprototype
The type of the remote socket does not match that of the local socket (sock_dgram vs. sock_stream ).
Eaddrinuse
The selected local address is occupied, or the file system socket object already exists.
Eisconn
Call connect (2) on a connected socket or specify the target address on a connected socket.
Enotconn
The socket operation requires a destination address, but the socket is not connected.
Econnreset
The remote socket is accidentally disabled.
Epipe
The remote socket is disabled on a stream socket. If activated, A sigpipe identifier will be sent at the same time. This can be avoided by passing the msg_nosignal identifier to sendmsg (2) or recvmsg (2.
Efault
The user memory address is invalid.
Eperm
The sender passes invalid credit certificates in struct ucred.
When a file system socket object is generated, other errors may be generated by the common socket layer or file system. For more information, see the appropriate manual page.
Practice:
A server program that uses a socket to implement inter-process communication in a Unix domain. First, the Program establishes a socket for the listening connection by calling the socket function, and then calls the BIND function to associate the socket with the address information. Call the listen function to listen to this port. When there is a connection request, call the accept function to establish a connection with the client. Finally, call the READ function to read the messages sent by the client, of course, you can also use the Recv function to implement the same function.
Server code: s_unix.c
// S_unix.c <br/> # include <stdio. h> <br/> # include <sys/types. h> <br/> # include <sys/socket. h> <br/> # include <sys/UN. h> <br/> # define unix_domain "/tmp/Unix. domain "<br/> int main (void) <br/>{< br/> socklen_t clt_addr_len; <br/> int listen_fd; <br/> int com_fd; <br/> int ret; <br/> int I; <br/> static char recv_buf [1024]; <br/> int Len; <br/> struct sockaddr_un clt_addr; <br/> struct sockaddr_un srv_addr; <br/> listen_fd = socket (pf_unix, sock_stream, 0); <br/> If (listen_fd <0) <br/>{< br/> perror ("cannot create communication socket"); <br/> return 1; <br/>}</P> <p> // set server addr_param <br/> srv_addr.sun_family = af_unix; <br/> strncpy (srv_addr.sun_path, unix_domain, sizeof (bytes) -1); <br/> unlink (unix_domain); <br/> // bind sockfd & ADDR <br/> ret = BIND (listen_fd, (struct sockaddr *) & srv_addr, sizeof (srv_addr); <br/> If (ret =-1) <br/>{< br/> perror ("cannot bind server socket "); <br/> close (listen_fd); <br/> unlink (unix_domain); <br/> return 1; <br/>}< br/> // listen sockfd <br/> ret = listen (listen_fd, 1); <br/> If (ret =-1) <br/>{< br/> perror ("cannot listen the client CONNECT request"); <br/> close (listen_fd); <br/> unlink (unix_domain ); <br/> return 1; <br/>}< br/> // have CONNECT request use accept <br/> Len = sizeof (clt_addr ); <br/> com_fd = accept (listen_fd, (struct sockaddr *) & clt_addr, & Len); <br/> If (com_fd <0) <br/>{< br/> perror ("cannot accept client CONNECT request"); <br/> close (listen_fd); <br/> unlink (unix_domain ); <br/> return 1; <br/>}< br/> // read and printf sent Client info <br/> printf ("/n ===== info =====/N" ); <br/> for (I = 0; I <4; I ++) <br/> {<br/> memset (recv_buf ); <br/> int num = read (com_fd, recv_buf, sizeof (recv_buf); <br/> printf ("Message from client (% d )): % s/n ", num, recv_buf); <br/>}< br/> close (com_fd); <br/> close (listen_fd ); <br/> unlink (unix_domain); <br/> return 0; <br/>}< br/>
A client program that uses a socket to implement inter-process communication in a Unix domain. Compared with the server program, the customer segment is relatively simple. The program first creates the socket required for communication by calling the socket function, and then calls the connect function to connect to the server. After the connection is established successfully, the program calls the write function to send the specified message to the server.
Client code: u_unix.c
// C_unix.c <br/> # include <stdio. h> <br/> # include <sys/types. h> <br/> # include <sys/socket. h> <br/> # include <sys/UN. h> <br/> # define unix_domain "/tmp/Unix. domain "<br/> int main (void) <br/>{< br/> int connect_fd; <br/> int ret; <br/> char snd_buf [1024]; <br/> int I; <br/> static struct sockaddr_un srv_addr; <br/> // creat UNIX socket <br/> connect_fd = socket (pf_unix, sock_stream, 0 ); <br/> If (connect_fd <0) <br/> {<br/> perror ("cannot create communication socket"); <br/> return 1; <br/>}< br/> srv_addr.sun_family = af_unix; <br/> strcpy (srv_addr.sun_path, unix_domain ); <br/> // connect server <br/> ret = connect (connect_fd, (struct sockaddr *) & srv_addr, sizeof (srv_addr )); <br/> If (ret =-1) <br/> {<br/> perror ("cannot connect to the server "); <br/> close (connect_fd); <br/> return 1; <br/>}< br/> memset (snd_buf, 0,1024); <br/> strcpy (snd_buf, "Message from client"); <br/> // send info server <br/> for (I = 0; I <4; I ++) <br/> write (connect_fd, snd_buf, sizeof (snd_buf); <br/> close (connect_fd); <br/> return 0; <br/>}</P> <p>
Compile and run:
[Root @ localhost liuxltest] #./s_unix &
[1] 11664
[Root @ localhost liuxltest] #./c_unix &
===== Info ====
Message from client (1024): Message from client
Message from client (1024): Message from client
Message from client (1024): Message from client
Message from client (1024): Message from client
[2] 11665
[1]-done./s_unix
[2] + done./c_unix
[Root @ localhost liuxltest] #
After running the s_unix program, the program will be in the listening state. In this case, you can run the netstat command to check the program running status. The s_unix socket type is stream socket and is in the listening status.
[Root @ localhost liuxltest] #
[Root @ localhost liuxltest] #./s_unix &
[1] 12056
[Root @ localhost liuxltest] # netstat-an | grep/tmp
UNIX 2 [ACC] stream listening 64014/tmp/ssh-CekOJ11069/agent.11069
UNIX 2 [ACC] stream listening 6216/tmp/. Font-UNIX/fs7100
UNIX 2 [ACC] stream listening 62042/tmp/ssh-XOCgkr9439/agent.9439
UNIX 2 [ACC] stream listening 62316/tmp/ssh-mojoaQ9648/agent.9648
UNIX 2 [ACC] stream listening 65267/tmp/Unix. Domain
UNIX 2 [ACC] stream listening 65210/tmp/ssh-NlKtA12012/agent.12012
[Root @ localhost liuxltest] #