About Linux IPC (i): socket-based interprocess communication (I.)

Source: Internet
Author: User

"Copyright Notice: respect for the original, reproduced please retain the source: blog.csdn.net/shallnet or .../gentleliu, the article is for learning communication only, do not use for commercial purposes"
In a larger project, there will generally be multiple processes, each function is a separate process running. Since multiple processes form a project, there is a certain amount of information exchanged or shared between multiple processes, which involves interprocess communication. There are many inter-process channels, such as the most familiar with the network programming socket, as well as shared memory, Message Queuing, signal, pipeline and many other ways, each of which has its own application, in this series of articles will be the author of a variety of inter-process communication methods to explain, One is to work for many years in this area of experience to do an accumulation, the second is to share it to you migrant workers, perhaps also from everyone's shot bricks to get unexpected harvest.

Socket network programming is probably the most used, often used for communication between different hosts on the network. In fact, in the same host communication can also be used to complete the socket, the socket process communication and network communication using a uniform set of interfaces, but the address structure and some parameters are different. When you create a socket by using the socket, the domain is af_inet (IPv4 Internet domain) or af_inet6 (IPv6 Internet domain) or Af_unix (Unix domain) by specifying the parameters.
In this article I have described in detail the creation of the socket communication process and the basic knowledge.
http://blog.csdn.net/shallnet/article/details/17734919.

First look at using the Af_inet domain and the local loopback address to implement the local host interprocess communication.
The service process creates a listener socket:
int ser_afinet_listen (int port) {    int                 listenfd, on;    struct sockaddr_in  seraddr;     LISTENFD = socket (af_inet, sock_stream, 0);    if (LISTENFD < 0) {        fprintf (stderr, "Socket:%s\n", Strerror (errno));        return-1;    }     on = 1;    SetSockOpt (LISTENFD, Sol_socket, so_reuseaddr, &on, sizeof (on));     seraddr.sin_family = af_inet;    Seraddr.sin_port = port;    SERADDR.SIN_ADDR.S_ADDR = htonl (inaddr_any);     if (Bind (LISTENFD, (struct sockaddr *) &seraddr, sizeof (struct sockaddr_in)) < 0) {        fprintf (stderr, "bind:%s\ N ", Strerror (errno));        return-1;    }     if (Listen (LISTENFD, Sock_ipc_max_conn) < 0) {        fprintf (stderr, "Listen:%s\n", Strerror (errno));        return-1;    }     return LISTENFD;}

The service process processes the connection request as follows:
int ser_accept (int listenfd) {    int                 connfd;    struct Sockaddr_un  cltaddr;    ssize_t             Recvlen, Sendlen;    Char                buf[sock_ipc_max_buf];    socklen_t           Addrlen;     Addrlen = sizeof (CLTADDR);    for (;;) {        CONNFD = Accept (LISTENFD, (struct sockaddr *) &cltaddr, &addrlen);        if (CONNFD < 0) {            fprintf (stderr, "Accept:%s\n", Strerror (errno));            return-1;        }         if (Recvlen = Ipc_recv (CONNFD, buf, sizeof (BUF)) < 0) {            continue;        }         printf ("Recv:%s\n", buf);        snprintf (buf, sizeof (BUF), "Hello, IPC client!");        if (Ipc_send (CONNFD, buf, strlen (buf)) < 0) {            continue;        }         Close (CONNFD);    
The client process is initialized as follows:
Specifies that the server address to be connected is a local swap-back address, so that the sent connection will return to the local service process.
int clt_afinet_conn_init (int port) {    int                 fd;     FD = socket (af_inet, sock_stream, 0);    if (FD < 0) {        fprintf (stderr, "Socket:%s\n", Strerror (errno));        return-1;    }     seraddr.sin_family = af_inet;    Seraddr.sin_port = port;    if (Inet_pton (af_inet, "127.0.0.1", &seraddr.sin_addr) < 0) {//loopback address        fprintf (stderr, "Inet_pton:%s\n", Strerror (errno));        return-1;    }     return FD;}

The client process sends a receive request to the service process as follows:
if (Connect (fd, (struct sockaddr *) &seraddr, sizeof (struct sockaddr_in)) < 0) {        fprintf (stderr,  "Connect :%s\n ", Strerror (errno));        return-1;    }     if (Sendlen = Ipc_send (FD, buf, strlen (BUF))) < 0) {        return-1;    }     if (Recvlen = Ipc_recv (fd, buf, sizeof (BUF))) < 0) {        return-1;    

The service process runs first, and the client process executes:
#./client
Recv:hello, IPC client!
#./server
Recv:hello IPC server!
The communication process is complete.
Creates a socket of type Af_unix (or af_local) that is used for process communication.
The socket process communicates with network communication using a uniform set of interfaces:
#include <sys/socket.h>int socket (int domain, int type, int protocol);
Where the domain parameter specifies the protocol family, for the local socket, its value is set to Af_unix enumeration value, casually say, Af_unix and af_local is the same value, look at the following Linux/socket.h header file section below, two macro values are the same as 1.
         .../* Supported address families. */#define AF_UNSPEC       0#define Af_unix         1/       * UNIX domain sockets */          #define AF_LOCAL        1/       * POSIX Name for Af_unix       */#define AF_INET         2/       * Internet IP Protocol         */#define AF_AX25         3/       * Amateur Radio ax.25          */...
The fields beginning with af_xx and pf_xx are the same, and continue to see the contents of the file part of everything is clear:
... #define PF_UNSPEC       af_unspec#define pf_unix         af_unix#define pf_local        af_local#define pf_inet         af_ Inet#define pf_ax25         af_ax25 ...
So when we specify the type of socket, these four fields can be used casually, the author here unified use Af_unix.
The type parameter can be set to SOCK_STREAM (stream socket) or SOCK_DGRAM (datagram socket), and for a local socket, a streaming socket (SOCK_STREAM) is a sequential, reliable, bidirectional byte stream. The equivalent of establishing a data channel between the local processes, the datagram socket (SOCK_DGRAM) is equivalent to a simple sending message, in the process of communication, theoretically there may be information loss, replication or not in order to arrive, but because of its local communication, not through the outside network, The probability of these occurrences is very small.
Both sides of the local socket need to have a local address, and the address type is a struct sockaddr_un struct (located at Linux/un.h):
#ifndef _linux_un_h#define _linux_un_h #define UNIX_PATH_MAX   108 struct Sockaddr_un {        sa_family_t sun_family; * Af_unix */        char Sun_path[unix_path_max];   /* pathname */}; #endif/* _linux_un_h */
To create a listener socket:
int Ser_afunix_listen (const char *pathname) {    int                 listenfd, on;    struct Sockaddr_un  seraddr;     LISTENFD = socket (Af_unix, sock_stream, 0);    if (LISTENFD < 0) {        fprintf (stderr, "Socket:%s\n", Strerror (errno));        return-1;    }     Unlink (pathname);    seraddr.sun_family = Af_unix;    snprintf (Seraddr.sun_path, sizeof (Seraddr.sun_path), "%s", pathname);     if (Bind (LISTENFD, (struct sockaddr *) &seraddr, sizeof (struct sockaddr_un)) < 0) {        fprintf (stderr, "bind:%s\ N ", Strerror (errno));        return-1;    }     if (Listen (LISTENFD, Sock_ipc_max_conn) < 0) {        fprintf (stderr, "Listen:%s\n", Strerror (errno));        return-1;    }     return LISTENFD;}
The service process handles the connection request similar to the above network traffic.

The client process initializes the socket procedure as:
int clt_afunix_conn_init (const char *pathname) {    int                 fd;    struct Sockaddr_un  localaddr;     FD = socket (Af_unix, sock_stream, 0);    if (FD < 0) {        fprintf (stderr, "Socket:%s\n", Strerror (errno));        return-1;    }     localaddr.sun_family = Af_unix;    snprintf (Localaddr.sun_path, sizeof (Localaddr.sun_path), "%s-cltid%d", Pathname, Getpid ());     if (Bind (FD, (struct sockaddr *) &localaddr, sizeof (struct sockaddr_un)) < 0) {        fprintf (stderr, "bind:%s\n", S Trerror (errno));        return-1;    }     seraddr.sun_family = Af_unix;    snprintf (Seraddr.sun_path, sizeof (Seraddr.sun_path), "%s", pathname);     return FD;}

The client process sends a receive request to the service process similar to the above network traffic.
Run the results with the network communication section.
This section only gives a very simple communication program that simply implements the communication between the client process and the service process, and in the next section I'll make a modification on the basis of the example in this section to write a code that can be used in the actual application.
This section is a sample code download link:
http://download.csdn.net/detail/gentleliu/8140459

About Linux IPC (i): socket-based interprocess communication (I.)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.