linux下实现两人、三人无序对话功能

 序:引子

对话功能实际上就是利用管道见得通信。最原始的是一方发另一方收,不能进项交互,发送方的代码如下:

 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 }
send.c

接收方的代码:

 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 }
recev.c

两人回话

对于两个程序之间的进行交互式对话有两种方式:

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 }
send.c
recev_send.c

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 }
fork_re_se.c
 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 }
fork_se_re.c

三人无序对话

本程序主要通过父进程创建两个子进程,通过管道来实现,和两人无序对话的功能一样。只要逻辑清晰,并不难。共需要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
 以上表格表示的具体含义我在这里举例说明一下。eg:对于A(聊天猪头)而言共有四根管道与其相连,两根用于读,另外两根用于写,1-2管道代表A、B之间的管道A需要进行写操作,而B进行读操作。 
  • A:第一人
 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.c
  • B:第二人
 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 }
2.c
  • C:第三人
 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 }
3.c

 PS:在命令行参数中还需注意的,假设1.c、2.c、3.c的可执行文件为A.out、B.out、C.out。命令行参数分别为:(其实和表格里分析的一样)

            1. ./A.out   12.fifo  13.fifo  21.fifo   31.fifo
            2. ./B.out   12.fifo  21.fifo  23.fifo   32.fifo
            3. ./C.out   13.fifo  31.fifo  23.fifo   32.fifo

 三人以上的用fork就没必要了,需要另寻方,一般采用服务器的处理方式。

posted @ 2014-08-23 00:04  donald_su  阅读(331)  评论(0编辑  收藏  举报