About Linux IPC (ii): socket-based interprocess communication (bottom)

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 two process communication, there are two processes that exchange information with each other, and some are more complex than the previous section. In general, there is a service process that waits for the client process to connect, and the client process and the service process have the following three ways of exchanging data:
The client process sends a request for a global data from the service process, and the service process returns the data (for short, get requests);
The client process sends a request to set the service process global data (for short, set request);
The client process sends a request to set the service process global data, and returns a data after the service process is set, (set and get coexist);

In this section we will complete a socket interprocess communication that can be used in real-world applications.
There may be many kinds of get and set requests described above, and the data used for each request is different, so we need to define a type for each request, where the service process can know what data the client process needs to process, and each request service process should return the resulting return value of its processing Since it is two process communication, there must be a data exchange, so there must be data sent and received, as well as the need to know the size of the data to the end. So we first define the data structure (similar to the TCP/IP protocol packet format) between two processes, based on this need:
typedef struct _IPC_SOCK_MSG_T {    int     msg_type;//request type    int     msg_rc;//Service process result return value    int     msg_ buflen;//the size of the interchange data    Char    msg_buf[sock_ipc_max_buf];//The contents of the interchange data} ipc_sock_msg_t;
When a service process receives a client process request, it first determines the type of request and processes it according to the request type. We first define an array of functions that all requests to be processed before the service process receives the request are registered with the function array, and the processing function is found based on the request type Index after the request is received.
The function array is as follows:
static int (*sln_ipc_ser_func[sln_ipc_max_type]) (        void *recvbuf, int recv_size,        void *sendbuf, int *send_size) ;

Before the service process receives processing, it registers the function that needs to be processed in the function array, as follows:
int Sln_ipc_ser_func_init (void) {    int     i;     for (i = 0; i < Sln_ipc_max_type; i++) {        sln_ipc_ser_func[i] = NULL;    }     SLN_IPC_SER_FUNC[SLN_IPC_TYPE_0X1] = sln_ipc_handle_0x1;    SLN_IPC_SER_FUNC[SLN_IPC_TYPE_0X2] = sln_ipc_handle_0x2;     return 0;}

After the service process starts listening, wait for the connection:
The listener code is similar to the previous section example:
#if Use_af_unix    fd = Sln_ipc_ser_afunix_listen (sock_ipc_name);    if (FD < 0) {        return-1;    } #else    fd = Sln_ipc_ser_afinet_listen (sock_ipc_ser_listen_port);    if (FD < 0) {        return-1;    } #endif

The service process receives the data sent by the client process and gives it to the function Sln_ser_handle to handle:
static intsln_ipc_ser_accept (int listenfd) {    int                 connfd;    ssize_t             Recvlen;    ipc_sock_msg_t      recv_msg;    socklen_t           Addrlen; #if use_af_unix    struct sockaddr_un  cltaddr; #else    struct sockaddr_in  cltaddr; #endif     addrlen = sizeof (CLTADDR);    for (;;) {        CONNFD = Accept (LISTENFD, (struct sockaddr *) &cltaddr, &addrlen);        if (CONNFD < 0) {            fprintf (stderr, "Accept:%s\n", Strerror (errno));            Continue;        }         if (Recvlen = Sln_ipc_recv (CONNFD, &recv_msg, sizeof (ipc_sock_msg_t))) < 0) {            continue;        }         Sln_ser_handle (CONNFD, &recv_msg);         Close (CONNFD);    }     return 0;}

Where the handler function Sln_ser_handle is implemented as:
static intsln_ser_handle (int sockfd, ipc_sock_msg_t *recv_msg) {    ipc_sock_msg_t  send_msg;     memset (&send_msg, 0, sizeof (ipc_sock_msg_t));     Send_msg.msg_type = recv_msg->msg_type;       if ((Recv_msg->msg_type >= sln_ipc_max_type)        && (RECV_MSG->MSG_RC < 0)) {       SEND_MSG.MSG_RC = Sln_ipc_rc_type;    } else if (NULL = = Sln_ipc_ser_func[recv_msg->msg_type]) {        SEND_MSG.MSG_RC = Sln_ipc_rc_func;    } else {        SEND_MSG.MSG_RC            = Sln_ipc_ser_func[recv_msg->msg_type] (                    recv_msg->msg_buf,                    recv_msg-> Msg_buflen,                    send_msg.msg_buf,                    &send_msg.msg_buflen);    }     if (Sln_ipc_send (SOCKFD, &send_msg, sizeof (ipc_sock_msg_t)) < 0) {        return-1;    }     return 0;}                    

Call the service process handler that is registered at initialization time in function Sln_ser_handle to complete the request of the client process. The two functions that initialize the registration are:
static char     gbuf[256] = "Hello, this is server!"; intsln_ipc_handle_0x1 (void *recvbuf, int recv_size, void *sendbuf, I NT *send_size) {    printf ("=============%s->%d===========\n", __func__, __line__);    memcpy (SendBuf, Gbuf, strlen (GBUF));     *send_size = strlen (gbuf);     return SLN_IPC_RC_OK;} intsln_ipc_handle_0x2 (void *recvbuf, int recv_size, void *sendbuf, int *send_size) {    printf ("=============%s->% D===========\n ", __func__, __line__);    memcpy (Gbuf, Recvbuf, recv_size);     *send_size = 0;     return SLN_IPC_RC_OK;}

The processing function takes 4 parameters, namely: Receive data buffer, received data size, send data buffer, send data size. The first two parameters are input parameters, the last two parameters are the parameters that return the output, the service process needs to process the customer request according to the data sent by the customer process, and then return the data that the service process needs to return and the result (completion or failure), and the processing result is returned in the return value of the handler function.
Here's a look at the implementation of the customer process:
Intsln_ipc_clt_conn (int msg_type, int *ret_code, void *sendbuf, int sendlen, void *rec    vbuf, int *recvlen) {int connfd;    ssize_t ret_size;    Socklen_t Addrlen; ipc_sock_msg_t send_msg, recv_msg;    #if Use_af_unix if (connfd = Sln_ipc_clt_afunix_conn_init (sock_ipc_name)) < 0) {return-1; } addrlen = sizeof (struct sockaddr_un), #else if (connfd = Sln_ipc_clt_afinet_conn_init (sock_ipc_ser_listen_port)) & Lt    0) {return-1;  } addrlen = sizeof (struct sockaddr_in), #endif if (Connect (CONNFD, (struct sockaddr *) &seraddr, Addrlen) < 0)        {fprintf (stderr, "Connect:%s\n", Strerror (errno));    return-1;    } memset (&send_msg, 0, sizeof (ipc_sock_msg_t));    Send_msg.msg_type = Msg_type;        if (NULL! = sendbuf) {Send_msg.msg_buflen = Sendlen;    memcpy (Send_msg.msg_buf, SendBuf, Sendlen); } if (ret_size = Ipc_send (CONNFD,&AMP;SEND_MSG, 3 * sizeof (int) + Sendlen)) < 0) {return-1;    } if ((Ret_size = Ipc_recv (CONNFD, &recv_msg, sizeof (ipc_sock_msg_t))) < 0) {return-1;        } if (Recv_msg.msg_type! = send_msg.msg_type) {printf ("Error msg type!\n");    return-1;    } *ret_code = RECV_MSG.MSG_RC;        if (NULL! = recvbuf) {*recvlen = Recv_msg.msg_buflen;    memcpy (Recvbuf, Recv_msg.msg_buf, Recv_msg.msg_buflen); } return 0;}

The interface that the client process invokes is simpler to implement, just to tell the service process the type of processing I requested (Msg_type), and the data (SENDBUF) and size (Sendlen) that need to be transferred, the service process returns the processing result (ret_ Code) and the return data (RECVBUF) and size (Recvlen).
Example source code for this section:
http://download.csdn.net/detail/gentleliu/8140479

About Linux IPC (ii): socket-based interprocess communication (bottom)

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.