#include <errno.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/wait.h> #include <string.h> /**//* return how many char have got, if 0 fail to execute, else success */ int sendDev(constchar*exec_full_path, constchar*str_req, int len_req, char*str_resp, int size_resp) ...{ int fd[2], parent, child; pid_t pid; /**//* Create a duplex pipe using the BSD socketpair call */ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) <0) ...{ return0; } /**//* Fork the process and check whether it is successful */ if ( (pid = fork()) <0) ...{ close(fd[0]); close(fd[1]); return0; } parent = fd[0]; child = fd[1]; if (pid ==0) ...{ /**//* child */ /**//* Close the other end */ close(parent); /**//* prepare child fd as string */ char str_child_fd[16]; sprintf(str_child_fd, "%d", child); /**//* execl bin file and set child fd as param */ execl(exec_full_path, str_child_fd, NULL); close(child); /**//* Exit the child process if execl fails */ _exit(127); }else...{ /**//* parent */ /**//* Close the other end */ close(child); int n; /**//* send request xml string */ n = write(parent, str_req, len_req); shutdown(parent, SHUT_WR); /**//* read response xml string */ // Here, we set timeout policy, if sub process timeout, we just return zero fd_set rdfds; FD_ZERO(&rdfds); FD_SET(parent, &rdfds); struct timeval tv; tv.tv_sec =10; tv.tv_usec =0; n = select(parent+1, &rdfds, NULL, NULL, &tv); if(n ==0) ...{ /**//* timeout or not response */ close(child); } else...{ /**//* get the response string successfully */ n = read(parent, str_resp, size_resp); printf("read (%d) ", n); } close(parent); return n; } } int main(void) ...{ char exec[] ="/root/Desktop/p2"; char request[] ="<?xml version="1.0" encoding="utf-8"?><InputParam>P1 request...</InputParam>"; char response[1024]; memset(response, 0, 1024); int n = sendDev(exec, request, strlen(request), response, 1024); printf("P1 get (%d) -> %s ", n, response); return0; }
P2代码如下:
#include <errno.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/wait.h> #include <string.h> int main(int argc, char*argv[]) ...{ int n; int fd; sscanf(argv[0], "%d", &fd); /**//* read */ char buffer[1024]; memset(buffer, 0, 1024); n = read(fd, buffer, 1024); printf("P2 get (%d) -> %s ", n, buffer); sleep(5); /**//* write */ char response[] ="<?xml version="1.0" encoding="utf-8"?><OutputParam>P2 response...</OutputParam>"; n = write(fd, response, strlen(response)); printf("p2 wrote %d bytes. ", n); shutdown(fd, SHUT_WR); exit(0); }
编译P1, P2 gcc p1.c -o p1 gcc p2.c -o p2
运行P1 ./p1
运行结果如下:
P2 get (76) -> <?xml version="1.0" encoding="utf-8"?><InputParam>P1 request...</InputParam> p2 wrote 79 bytes. read (79) P1 get (79) -> <?xml version="1.0" encoding="utf-8"?><OutputParam>P2 response...</OutputParam>
Good job.
注意:我们也可以把Child重定向到stdin和stdout
dup2 (child, STDIN_FILENO); /**//* bind the pipe with STDIN */ dup2 (child, STDOUT_FILENO); /**//* bind the pipe with STDOUT */
这样,在子进程中就可以通过读stdin获取数据,写stdout发送数据
/**//**//**//* 获取数据 */ fgets(buf, 1024, stdin);; /**//**//**//* 写入数据 */ fputs(buf, stdout); fflush(stdout);/**//* ATT: We should use fflush in here */