爲了符合新的架構,需要實現進程間的雙向傳輸數據模型,今天下午做了一些研究,並把研究成果記錄下來。
很簡單,有兩個進程,P1進程調用P2進程,並且P1和P2進程進行雙向數據的傳輸。
P1代碼如下:
#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(const char *exec_full_path, const char *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) {
return 0;
}
/* Fork the process and check whether it is successful */
if ( (pid = fork()) < 0) {
close(fd[0]);
close(fd[1]);
return 0;
}
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);
return 0;
}
P2代碼如下:
#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, STDOUT_FILENO); /* bind the pipe with STDOUT */
fgets(buf, 1024, stdin);;
/**//* 寫入數據 */
fputs(buf, stdout);
fflush(stdout);/* ATT: We should use fflush in here */