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就没必要了,需要另寻方,一般采用服务器的处理方式。

你可能感兴趣的:(linux)