对话功能实际上就是利用管道见得通信。最原始的是一方发另一方收,不能进项交互,发送方的代码如下:
1 /*============================================ 2 > Copyright (C) 2014 All rights reserved. 3 > FileName:send.c 4 > author:donald 5 > details: 6 ==============================================*/ 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 #include <sys/types.h> 11 #include <sys/stat.h> 12 #include <fcntl.h> 13 #define N 1024 14 int main(int argc, const char *argv[]) 15 { 16 17 if(-1 == mkfifo(argv[1],0666)){//creat 2 18 perror("failed"); 19 exit(-1); 20 } 21 22 printf("mkfifo over!\n"); 23 int fd_send,fd_recev; 24 printf("open fifo...\n"); 25 26 27 fd_send = open(argv[1],O_WRONLY); 28 29 if(fd_send == -1){//必须另一方打开 30 perror("open failed"); 31 unlink(argv[1]); 32 exit(-1); 33 } 34 printf("open success!\n"); 35 36 char send_buf[N]; 37 while(memset(send_buf,0,N),fgets(send_buf,N,stdin) != NULL){ 38 write(fd_send,send_buf,strlen(send_buf)); 39 } 40 41 printf("send over\n"); 42 unlink(argv[1]); 43 return 0; 44 }
接收方的代码:
1 /*============================================ 2 > Copyright (C) 2014 All rights reserved. 3 > FileName:recv.c 4 > author:donald 5 > details: 6 ==============================================*/ 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 #include <sys/types.h> 11 #include <sys/stat.h> 12 #include <fcntl.h> 13 #define N 1024 14 int main(int argc, const char *argv[]) 15 { 16 int fd_send,fd_recev; 17 printf("open fifo...\n"); 18 fd_recev = open(argv[1],O_RDONLY); 19 20 if(fd_send == -1){ 21 perror("open failed"); 22 unlink(argv[1]); 23 exit(-1); 24 } 25 printf("open success!\n"); 26 27 char recev_buf[1024]; 28 while(memset(recev_buf,0,N),read(fd_recev,recev_buf,N) > 0){ 29 printf("%s",recev_buf); 30 } 31 32 printf("recev over\n"); 33 close(fd_recev); 34 unlink(argv[1]); 35 return 0; 36 }
对于两个程序之间的进行交互式对话有两种方式:
A.一问一答式,这是最简单的方式,但也是最不人性化的方法,运行后你就会产生一种回到上个世纪的错觉
B.没有固定的顺序,和QQ一样,想说就说,不用等到另一方说完一句才能说。
A方法比较简单,直接上代码:
启动方:
1 /*============================================ 2 > Copyright (C) 2014 All rights reserved. 3 > FileName:send.c 4 > author:donald 5 > date:2014/08/22/ 14:45:45 6 > details: 7 ==============================================*/ 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <sys/types.h> 12 #include <sys/stat.h> 13 #include <fcntl.h> 14 #define N 1024 15 int main(int argc, const char *argv[]) 16 { 17 18 if(-1 == mkfifo(argv[1],0666)){//creat 1 19 perror("failed"); 20 exit(-1); 21 } 22 23 printf("mkfifo over!\n"); 24 int fd_send,fd_recev; 25 printf("open fifo...\n"); 26 27 fd_send = open(argv[1],O_WRONLY); 28 29 if(fd_send == -1){//必须另一方打开 30 perror("open failed"); 31 unlink(argv[1]); 32 // exit(-1); 33 } 34 printf("open success!\n"); 35 36 char send_buf[N]; 37 while(memset(send_buf,0,N),fgets(send_buf,N,stdin) != NULL){ 38 write(fd_send,send_buf,strlen(send_buf)); 39 } 40 41 printf("send over\n"); 42 unlink(argv[1]); 43 return 0; 44 }
B方法利用创建一个进程(fork)来实现交互,其代码为:
1 /*=========================================== 2 > Copyright (C)2014All rights reserved 3 > File Name: fork_re_se.c 4 > Author: Donald 5 =============================================*/ 6 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 #include <sys/types.h> 11 #include <sys/stat.h> 12 #include <fcntl.h> 13 #define N 1024 14 int main(int argc, const char *argv[]) 15 { 16 #if 1 17 if(-1 == mkfifo(argv[1],0666)){ 18 perror("failed"); 19 exit(-1); 20 } 21 printf("mkfifo over!\n"); 22 #endif 23 int fd_send,fd_recev; 24 printf("open fifo...\n"); 25 fd_recev = open(argv[1],O_RDONLY); 26 fd_send = open(argv[2],O_WRONLY); 27 28 if(fd_send == -1 || fd_recev == -1){ 29 perror("open failed"); 30 unlink(argv[2]); 31 exit(-1); 32 } 33 printf("open success!\n"); 34 35 char recev_buf[1024]; 36 char send_buf[N]; 37 if(fork() == 0){//child recev 38 close(fd_send); 39 //while(memset(recev_buf,0,N),read(fd_recev,recev_buf,strlen(recev_buf)) != 0){这里不能用strlen(recev_buf在while中进行了初始化,所以长度为0) 40 while(memset(recev_buf,0,N),read(fd_recev,recev_buf,N) != 0){ 41 //write(1,recev_buf,N); 42 printf("%s",recev_buf); 43 } 44 exit(1); 45 }else{//parent send 46 close(fd_recev); 47 while(memset(send_buf,0,N),fgets(send_buf,N,stdin) != NULL){ 48 write(fd_send,send_buf,strlen(send_buf)); 49 } 50 close(fd_send); 51 wait(NULL); 52 unlink(argv[1]); 53 } 54 printf("recev over\n"); 55 return 0; 56 }
1 /*=========================================== 2 > Copyright (C)2014All rights reserved 3 > File Name: fork_se_re.c 4 > Author: Donald 5 =============================================*/ 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <sys/types.h> 10 #include <sys/stat.h> 11 #include <fcntl.h> 12 #define N 1024 13 int main(int argc, const char *argv[]) 14 { 15 #if 1 16 if(-1 == mkfifo(argv[2],0666)){ 17 perror("failed"); 18 exit(-1); 19 } 20 printf("mkfifo over!\n"); 21 #endif 22 int fd_send,fd_recev; 23 printf("open fifo...\n"); 24 fd_send = open(argv[1],O_WRONLY); 25 fd_recev = open(argv[2],O_RDONLY); 26 27 if(fd_send == -1 || fd_recev == -1){ 28 perror("open failed"); 29 unlink(argv[2]); 30 exit(-1); 31 } 32 printf("open success!\n"); 33 34 char recev_buf[1024]; 35 char send_buf[N]; 36 if(fork() == 0){//child recev 37 close(fd_send); 38 while(memset(recev_buf,0,N),read(fd_recev,recev_buf,N) != 0){ 39 //write(1,recev_buf,N); 40 printf("%s",recev_buf); 41 } 42 exit(1); 43 }else{//parent send 44 close(fd_recev); 45 while(memset(send_buf,0,N),fgets(send_buf,N,stdin) != NULL){ 46 write(fd_send,send_buf,strlen(send_buf)); 47 } 48 close(fd_send); 49 wait(NULL); 50 unlink(argv[2]); 51 } 52 53 printf("send over\n"); 54 return 0; 55 }
本程序主要通过父进程创建两个子进程,通过管道来实现,和两人无序对话的功能一样。只要逻辑清晰,并不难。共需要pipe(有名管道)六根,功能为用于读、写,为了使逻辑清晰,方便讨论,以下1、2、3分别代表程序1、2、3之间的管道,分别对程序之间的管道进项讨论分析:
A | B | C | |||
1-2 | write | 1-2 | read | 1-3 | read |
1-3 | write | 2-1 | write | 3-1 | write |
2-1 | read | 2-3 | write | 2-3 | read |
3-1 | read | 3-2 | read | 3-2 | write |
1 /*============================================ 2 > Copyright (C) 2014 All rights reserved. 3 > FileName:1.c 4 > author:donald 5 > date:2014/08/22/ 20:28:53 6 > details: 7 ==============================================*/ 8 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <sys/types.h> 13 #include <sys/stat.h> 14 #include <fcntl.h> 15 #define N 1024 16 int main(int argc, const char *argv[])//12,13,21,31 17 { 18 if(mkfifo(argv[1],0666) == -1 || mkfifo(argv[2],0666) == -1){ 19 perror("mkfifo"); 20 exit(1); 21 } 22 23 int fd_12,fd_13,fd_21,fd_31; 24 char buf[N]; 25 fd_12 = open(argv[1],O_WRONLY); 26 fd_13 = open(argv[2],O_WRONLY); 27 fd_21 = open(argv[3],O_RDONLY); 28 fd_31 = open(argv[4],O_RDONLY); 29 30 printf("open sucess\n"); 31 32 if(fork() == 0){//21 r 33 close(fd_13); 34 close(fd_12); 35 close(fd_31); 36 while(memset(buf,0,N),read(fd_21,buf,N) != 0){ 37 printf("from 2:"); 38 write(1,buf,strlen(buf)); 39 } 40 close(fd_21); 41 exit(1); 42 } 43 if(fork() == 0){//31 r 44 close(fd_13); 45 close(fd_12); 46 close(fd_21); 47 while(memset(buf,0,N),read(fd_31,buf,N) != 0){ 48 printf("from 3:"); 49 write(1,buf,strlen(buf)); 50 } 51 close(fd_31); 52 exit(1); 53 } 54 55 //12 13 w 56 close(fd_21); 57 close(fd_31); 58 while(memset(buf,0,N),fgets(buf,N,stdin) != NULL){ 59 write(fd_13,buf,strlen(buf)); 60 write(fd_12,buf,strlen(buf)); 61 } 62 close(fd_13); 63 close(fd_12); 64 wait(NULL); 65 wait(NULL); 66 67 unlink(argv[1]); 68 unlink(argv[2]); 69 printf("program 1 over\n"); 70 return 0; 71 }
1 /*============================================ 2 > Copyright (C) 2014 All rights reserved. 3 > FileName:2.c 4 > author:donald 5 > date:2014/08/22/ 20:29:02 6 > details: 7 ==============================================*/ 8 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <sys/types.h> 13 #include <sys/stat.h> 14 #include <fcntl.h> 15 #define N 1024 16 int main(int argc, const char *argv[]) 17 { 18 19 if(mkfifo(argv[2],0666) == -1 || mkfifo(argv[3],0666) == -1){ 20 perror("mkfifo"); 21 exit(1); 22 } 23 24 int fd_12,fd_21,fd_23,fd_32; 25 char buf[N]; 26 fd_12 = open(argv[1],O_RDONLY); 27 fd_21 = open(argv[2],O_WRONLY); 28 fd_23 = open(argv[3],O_WRONLY); 29 fd_32 = open(argv[4],O_RDONLY); 30 31 printf("open success\n"); 32 33 if(fork() == 0){//12 r 34 close(fd_32); 35 close(fd_21); 36 close(fd_23); 37 while(memset(buf,0,N),read(fd_12,buf,N) != 0){ 38 printf("from 1:"); 39 write(1,buf,strlen(buf)); 40 } 41 close(fd_12); 42 exit(1); 43 } 44 45 if(fork() == 0){//32 r 46 close(fd_12); 47 close(fd_21); 48 close(fd_23); 49 while(memset(buf,0,N),read(fd_32,buf,N) != 0){ 50 printf("from 3:"); 51 write(1,buf,strlen(buf)); 52 } 53 close(fd_32); 54 exit(1); 55 } 56 57 //21 23 w 58 close(fd_12); 59 close(fd_32); 60 while(memset(buf,0,N),fgets(buf,N,stdin) != NULL){ 61 write(fd_21,buf,strlen(buf)); 62 write(fd_23,buf,strlen(buf)); 63 } 64 close(fd_21); 65 close(fd_23); 66 wait(NULL); 67 wait(NULL); 68 69 unlink(argv[2]); 70 unlink(argv[3]); 71 printf("program 2 over\n"); 72 return 0; 73 }
1 /*============================================ 2 > Copyright (C) 2014 All rights reserved. 3 > FileName:3.c 4 > author:donald 5 > date:2014/08/22/ 20:29:13 6 > details: 7 ==============================================*/ 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <sys/types.h> 12 #include <sys/stat.h> 13 #include <fcntl.h> 14 #define N 1024 15 int main(int argc, const char *argv[]) 16 { 17 18 if(mkfifo(argv[2],0666) == -1 || mkfifo(argv[4],0666) == -1){ 19 perror("mkfifo"); 20 exit(1); 21 } 22 23 int fd_13,fd_31,fd_23,fd_32; 24 char buf[N]; 25 fd_13 = open(argv[1],O_RDONLY); 26 fd_31 = open(argv[2],O_WRONLY); 27 fd_23 = open(argv[3],O_RDONLY); 28 fd_32 = open(argv[4],O_WRONLY); 29 30 printf("open success\n"); 31 32 if(fork() == 0){//13 r 33 close(fd_31); 34 close(fd_23); 35 close(fd_32); 36 while(memset(buf,0,N),read(fd_13,buf,N) != 0){ 37 printf("from 1:"); 38 write(1,buf,strlen(buf)); 39 } 40 close(fd_13); 41 exit(1); 42 } 43 if(fork() == 0){//23 r 44 close(fd_13); 45 close(fd_31); 46 close(fd_32); 47 while(memset(buf,0,N),read(fd_23,buf,N) != 0){ 48 printf("from 2:"); 49 write(1,buf,strlen(buf)); 50 } 51 close(fd_23); 52 exit(1); 53 } 54 55 //31 32 w 56 close(fd_13); 57 close(fd_23); 58 while(memset(buf,0,N),fgets(buf,N,stdin) != NULL){ 59 write(fd_31,buf,strlen(buf)); 60 write(fd_32,buf,strlen(buf)); 61 } 62 close(fd_31); 63 close(fd_32); 64 wait(NULL); 65 wait(NULL); 66 67 unlink(argv[2]); 68 unlink(argv[4]); 69 printf("program 3 over\n"); 70 return 0; 71 }
PS:在命令行参数中还需注意的,假设1.c、2.c、3.c的可执行文件为A.out、B.out、C.out。命令行参数分别为:(其实和表格里分析的一样)
三人以上的用fork就没必要了,需要另寻方,一般采用服务器的处理方式。