今天我们就用前面所学的有名管道mkfifo实现一个简易版的QQ对话功能。
步骤一:首先创建两个进程talkA.c和talkB.c;
步骤二:talkA.c和talkB.c负责查看是否已经创建了两个管道,如果没有则需要创建管道;
步骤三:talkA.c以只写的方式打开管道1;以只读的方式打开管道2;然后循环的写读数据
while(1)
{
获取键盘录入fgets
写管道1
读管道2
}
步骤四:talkB.c以只读的方式打开管道1;以只写的方式打开管道2;循环的读写数据
while(1)
{
读管道1
获取键盘录入fgets
写管道
}
通过写完以上步骤后就可以写代码了,通过把代码写完后运行如下:
talkA.c的运行结果:
talkB.c的运行结果
通过观察你会发现,只能当A向B发出一个信号后,这时候B是可以收到A发来的信号的;但是如果你连续从A向B发送几个信号后,B只能收到一个信号,剩下的信号都阻塞在里面了,只有B再给A发送一个信号后才能收到阻塞在缓冲器中的信号。
解决办法:
分别在A和B中添加父子进程,让A中的"读"放在父进程中,让A中的“写"放在子进程中;
同理:让B中的"读"放在父进程中,让A中的“写"放在子进程中。
这样就可以实现聊天自由了,不用担心连续发送好几个信号后对方只收到一个信号。
接下来看两个代码:
先看talkA.c
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <fcntl.h>
4 #include <sys/stat.h>
5 #include <sys/types.h>
6 #include <stdlib.h>
7 #include <string.h>
8 int main()
9 {
10 int ret=access("fifo1",F_OK);
11 if(ret==-1)
12 {
13 printf("没有管道,正在创建中....");
14 ret=mkfifo("fifo1",0664);
15 if(ret==-1)
16 {
17 perror("mkfifo");
18 exit(0);
19 }
20 }
21 ret=access("fifo2",F_OK);
22 if(ret==-1)
23 {
24 printf("没有管道,正在创建中....");
25 ret=mkfifo("fifo1",0664);
26 if(ret==-1)
27 {
28 perror("mkfifo");
29 exit(0);
30 }
31 }
32
33 int fd1=open("fifo1",O_WRONLY);//只写的方式打开管道
34 if(fd1==-1)
35 {
36 perror("open");
37 exit(0);
38 }
39
40 int fd2=open("fifo2",O_RDONLY);//只读的方式打开管道
41 if(fd2==-1)
42 {
43 perror("open");
44 exit(0);
45 }
46 pid_t pid=fork();
47 char str1[128];
48 if(pid>0)
49 {
50 while(1)
51 {
52 memset(str1,0,128);//每循环一次都要清空缓冲器
53 fgets(str1,128,stdin);//stdin 标准输入
54 int ret=write(fd1,str1,strlen(str1));
55 if(ret==-1)
56 {
57 perror("write");
58 exit(0);
59 }
60 }
61 }
62 if(pid==0)
63 {
64 while(1)
65 {
66 //5读管道数据
67 memset(str1,0,128);
68 int ret1=read(fd2,str1,128);
69 if(ret1<=0)
70 {
71 printf("读取失败....、\n");
72 exit(0);
73 }
74 printf("你说:%s\n",str1);
75 }
76 }
77 close(fd1);
78 close(fd2);
79 return 0;
80 }
talkB.c
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <fcntl.h>
4 #include <sys/stat.h>
5 #include <sys/types.h>
6 #include <stdlib.h>
7 #include <string.h>
8 int main()
9 {
10 int ret=access("fifo1",F_OK);
11 if(ret==-1)
12 {
13 printf("没有管道,正在创建中....");
14 ret=mkfifo("fifo1",0664);
15 if(ret==-1)
16 {
17 perror("mkfifo");
18 exit(0);
19 }
20 }
21 ret=access("fifo2",F_OK);
22 if(ret==-1)
23 {
24 printf("没有管道,正在创建中....");
25 ret=mkfifo("fifo2",0664);
26 if(ret==-1)
27 {
28 perror("mkfifo");
29 exit(0);
30 }
31 }
32 int fd1=open("fifo1",O_RDONLY);//只读的方式打开管道
33 if(fd1==-1)
34 {
35 perror("open");
36 exit(0);
37 }
38
39 int fd2=open("fifo2",O_WRONLY);//只写的方式打开管道
40 if(fd2==-1)
41 {
42 perror("open");
43 exit(0);
44 }
45 pid_t pid=fork();
46 char buf[128];
47 if(pid>0)
48 {
49 while(1)
50 {
51 memset(buf,0,128);//每循环一次都要清空缓冲器
52 int ret=read(fd1,buf,128);//读操作
53 if(ret<=0)
54 {
55 perror("read");
56 exit(0);
57 }
58 printf("你说:%s\n",buf);
59
60 }
61 }
62 if(pid==0)
63 {
64 while(1)
65 {
66 //写操作
67 memset(buf,0,128);
68 fgets(buf,128,stdin);
69 int ret1=write(fd2,buf,strlen(buf));
70 if(ret1==-1)
71 {
72 perror("write");
73 exit(0);
74 }
75
76 }
77 }
78 close(fd1);
79 close(fd2);
80 return 0;
81 }
等你写完一遍后自己试一试,可爽了。
这样的一个简易版聊天功能就做好了,如果情人节,你给你女朋友送个这个礼物,指不定对方有多高兴呢!