Basic concepts of interprocess communication
interprocess communication means that data can be exchanged between two different processes, but from the previous chapter we know that different processes are independent of each other, so to achieve different interprocess communication, there is a common area in which they can access the memory media, which is not a process, but the same as the socket, belonging to the operating system. So, two processes communicate through the memory space provided by the operating system, and we call this memory space a pipe.
Create a pipeline function
int pipe (int filedes[2]);
Returns 0 on success, 1 on Failure
Parameters:
Filedes[0]: The file descriptor used when receiving data through a pipeline, i.e., the pipe exit
FILEDES[1]: The file descriptor used when transferring data through a pipeline, that is, the pipeline entry
Examples are as follows:
#define Buf_sizeintMainintargcChar*argv[]) {intfds[2];//Save file descriptor for I/O Char Str[] ="who is?";CharBuf[buf_size]; pid_t pid; Pipe (FDS);//Create PipelinesPID = fork ();//Sub-process also replicates the I/O file descriptor if(PID = =0) {Write (fds[1],Str, sizeof (Str)); }Else{Read (fds[0], buf, buf_size); Puts (BUF); }return 0;}
The above example data is only one-way pass, think about if you want to do two-way delivery so you can? Because the data for the current pipeline is read by two processes, the read-ahead process takes the data from the pipeline first, so that the other process blocks and waits. Therefore, to achieve two-way communication between processes, it is difficult to implement a pipeline, we will discuss a simple implementation here-create two pipelines.
Two-way communication example:
#define Buf_sizeintMainintARGC, Char*ARGV[]){intfds1[2], fds2[2]; Char str1[] ="who is?"; Char str2[] ="Thank for your message"; Char Buf[buf_size]; pid_t pid;Pipe(FDS1),Pipe(FDS2); PID =Fork();if(PID = =0) {Write(fds1[1], str1, sizeof (STR1));//Send to Pipeline1 Read(fds2[0], buf, buf_size);//From the pipeline2Read inprintf("Child proc output: %s \ n", buf); }Else{Read(fds1[0], buf, buf_size);//From the pipeline1Read inprintf("Parent proc output: %s \ n", buf);Write(fds2[1], str2, sizeof (STR2));//Send to Pipeline2 Sleep(3); }return 0;}
Using interprocess communication
Here we extend the Echo program written in the previous section, and save the string from the client side to the server to the local file. We can delegate this task to another process, that is, to open a process on the service side to do this task, which involves the issue of inter-process data exchange.
////Main.cpp//Hello_server////Created by app05 on 15-8-19.//Copyright (c) 2015 APP05. All rights reserved.//#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/wait.h>#include <arpa/inet.h>#include <sys/socket.h>#include <signal.h>#define Buf_sizevoidError_handling (Char*message);voidRead_childproc (intSIG);intMainintargcConst Char* argv[]) {intServ_sock, Clnt_sock;structSockaddr_in Serv_adr, Clnt_adr;intfds[2]; pid_t pid;structSigaction Act; Socklen_t ADR_SZ;intStr_len, State;CharBuf[buf_size];if(ARGC! =2) {printf("Usage:%s <port> \ n", argv[0]);Exit(1); } Act.sa_handler = Read_childproc; Sigemptyset (&act.sa_mask); Act.sa_flags =0; State = Sigaction (SIGCHLD, &act,0); Serv_sock = socket (pf_inet, Sock_stream,0);memset(&serv_adr,0,sizeof(SERV_ADR)); serv_adr.sin_family = af_inet; SERV_ADR.SIN_ADDR.S_ADDR = htonl (Inaddr_any); Serv_adr.sin_port = htons (Atoi (argv[1]));if(Bind (Serv_sock, (structSOCKADDR *) &serv_adr,sizeof(SERV_ADR)) == -1) Error_handling ("bind () Error");if(Listen (Serv_sock,5) == -1) Error_handling ("Listen () Error");/ * Create child process to perform file write * /Pipe (FDS);//Create interchange Data PipelinePID =fork ();if(PID = =0) {FILE *FP = fopen ("/users/app05/desktop/server-clint/hello_server/hello_server/echonmsg.txt","WB");CharMsgbuf[buf_size];intI, Len; for(i =0; I <Ten; i++) {len = read (fds[0], Msgbuf, buf_size); Fwrite ((void*) Msgbuf,1, Len, FP); } fclose (FP);return 0; } while(1) {ADR_SZ =sizeof(CLNT_ADR); Clnt_sock = Accept (Serv_sock, (structSOCKADDR *) &clnt_adr, &ADR_SZ);if(Clnt_sock = =-1)Continue;Else puts("New client connected ..."); PID = fork ();if(PID = =-1) {Close (Clnt_sock);Continue; }if(PID = =0) {Close (Serv_sock); while((Str_len = Read (Clnt_sock, buf, buf_size))! =0) {Write (Clnt_sock, buf, Str_len); Write (fds[1], buf, Str_len);//Send data sent by customer service to the pipeline} close (Clnt_sock);puts("Client disconnected ...");return 0; }ElseClose (Clnt_sock); } close (Serv_sock);return 0;}voidError_handling (Char*message) {fputs(message, stderr); FPUTC (' \ n ', stderr);Exit(1);}voidRead_childproc (intSIG) {pid_t pid;intStatus PID = Waitpid (-1, &status, Wnohang);printf("removed proc ID:%d \ n", PID);}
Note: Like this multi-process server overhead, in practice we generally do not use this, the main purpose of this section and the previous section is to learn the theoretical knowledge of multiple processes.
There is also a problem with the socket closure here, the next boot on the permanent bind () failure, in addition, the data in the pipeline can not be read in the file, the specific reason unknown origin ..... ..... ..... ..... (preliminary estimate is the result of this multi-process operation ...)
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
TCP/IP network Programming Learning note _12-interprocess communication