有名管道(FIFO)实现无亲缘关系的客户服务器
来源:互联网 发布:雅思姐软件 编辑:程序博客网 时间:2024/06/04 23:22
FIFO(也称为有名管道)是first in first out的意思,也就是队列的特点。有名管道也是一个单向的数据流,但它与管道又有写区别。有名管道是有名字的,每一个FIFO对应于一个路径名,正因为这一点,有名管道可以允许非亲缘关系的进程访问同一个FIFO。另外,有名管道存在于磁盘当中,而管道存在于内存当中,通信结束后,有名管道的文件本身仍热存在,但是管道已经释放了。有名管道与文件也是有区别的,文件的话,当读取其中的内容之后,信息依然存在,但是有名管道中,通信结束之后,信息就会丢失。
有名管道的使用是得首先通过mkfifo()函数创建一个fifo,然后通过open()、write()、read()等函数进行操作,当最后使用完时,可以调用unlink()函数对fifo文件进行删除。
下面先看一个有名管道的简单应用程序:
- /*fifo.c*/
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #define FIFO_NAME "fifo_test"
- #define MAX 80
- int main()
- {
- pid_t pid;
- int fd;
- char buf[MAX]={0};
- unlink(FIFO_NAME); //为了防止FIFO_NAME文件存在
- mkfifo(FIFO_NAME, 0744); //创建fifo
- pid = fork();
- if(pid == 0) {
- fd = open(FIFO_NAME, O_RDONLY);
- while(read(fd, buf, MAX) != 0) {
- printf("read from fifo:%s\n", buf);
- }
- close(fd);
- } else if(pid > 0) {
- fd = open(FIFO_NAME, O_WRONLY);
- while(fgets(buf, MAX, stdin) != NULL) {
- buf[strlen(buf)-1] = 0; //deal with enter key
- write(fd, buf, MAX);
- }
- close(fd);
- wait(NULL); //等待子进程退出
- unlink(FIFO_NAME);
- } else {
- perror("fork error");
- exit(1);
- }
- return 0;
- }
这个程序的一次执行结果如下:
- ^_^[sunny@sunny-laptop ~/summer]121$ ./a.out
- sun //从键盘输入
- read from fifo:sun
- ls //从键盘输入
- read from fifo:ls
- open //从键盘输入
- read from fifo:open
- lovelinux //从键盘输入
- read from fifo:lovelinux //显示完毕之后,键入ctrol+D结束
- ^_^[sunny@sunny-laptop ~/summer]122$
程序说明:这个程序中,创建了一个进程,父进程以写的方式打开fifo,循环从键盘接收输入的字符串,之后去掉“\n”,将键盘接收到的字符串写入fifo中。对于子进程,以只读的方式打开fifo文件,之后从中读取写入的字符数据。这里应当注意一下:fifo写入的时候是写到fifo的末尾,读取的时候是从fifo的开始进行读取,而且fifo进行读写操作的时候,只有读端和写端同时都打开的时候才能进行相应的操作,否则,读取端和写入端都会陷入等待状态,并且有可能发生死锁状态,这点切记。
下面,进入我们的正题——通过有名管道实现无亲缘关系的客户与服务器模型。
下面的这个程序也是比较简单,不过不用急,我们慢慢对代码进行修改,由简单变复杂。这个程序主要是实现没有亲缘关系的两个进程进行通信,其中的client进程向fifo中循环写入数据,而在另外一个终端中运行的server进程,循环从fifo中读取数据并且显示出来。
- /*fifo_server.c*/
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #define FIFO_NAME "fifo_test"
- #define MAX 1024
- int main()
- {
- int fd;
- char buf[MAX]={0};
- fd = open(FIFO_NAME, O_RDONLY);
- while(read(fd, buf, MAX) != 0) {
- printf("read from client:%s\n", buf);
- }
- return 0;
- }
- /*fifo_client.c*/
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #define FIFO_NAME "fifo_test"
- #define MAX 1024
- int main()
- {
- int fd;
- char buf[MAX]={0};
-
- unlink(FIFO_NAME);
- mkfifo(FIFO_NAME, 0744);
- fd = open(FIFO_NAME, O_WRONLY);
- while(fgets(buf, MAX, stdin) != NULL) {
- buf[strlen(buf)-1] = 0; //是为了去掉回车符
- write(fd, buf, MAX);
- }
- unlink(FIFO_NAME);
- printf("connect over,exit successfully!\n");
- return 0;
- }
编译这两个程序:
- O_O[sunny@sunny-laptop ~/summer/fifo_rw]11$ gcc fifo_server.c -o server
- ^_^[sunny@sunny-laptop ~/summer/fifo_rw]12$ gcc fifo_client.c -o client
在一个终端执行:
- ^_^[sunny@sunny-laptop ~/summer/fifo_rw]13$ ./client
- sun //输入的数据
- open //输入的数据
- connect over,exit successfully!
- ^_^[sunny@sunny-laptop ~/summer/fifo_rw]14$
- ^_^[sunny@sunny-laptop ~/summer/fifo_rw]13$ ./client
在另外一个终端执行:
- ^_^[sunny@sunny-laptop ~/summer/fifo_rw]2$ ./server
- read from client:sun
- read from client:open
- ^_^[sunny@sunny-laptop ~/summer/fifo_rw]2$ ./server
这个简单的例子是半双工通信。为了实现全双工通信,我们需要两个fifo。程序代码如下:
- /*fifo_client.c*/
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #define FIFO_NAME1 "fifo_test1"
- #define FIFO_NAME2 "fifo_test2"
- #define MAX 1024
- int main()
- {
- int fd1, fd2;
- char buf[MAX]={0};
-
- unlink(FIFO_NAME1);
- unlink(FIFO_NAME2);
- mkfifo(FIFO_NAME1, 0744);
- mkfifo(FIFO_NAME2, 0744);
- fd1 = open(FIFO_NAME1, O_WRONLY);
- fd2 = open(FIFO_NAME2, O_RDONLY);
- while(fgets(buf, MAX, stdin) != NULL) {
- buf[strlen(buf)-1] = 0; //是为了去掉回车符
- write(fd1, buf, MAX);
- read(fd2, buf, MAX);
- printf("client read from server:%s\n", buf);
- }
- unlink(FIFO_NAME1);
- unlink(FIFO_NAME2);
- printf("connect over,exit successfully!\n");
- return 0;
- }
- /*fifo_server.c*/
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #define FIFO_NAME1 "fifo_test1"
- #define FIFO_NAME2 "fifo_test2"
- #define MAX 1024
- int main()
- {
- int fd1, fd2;
- char buf[MAX]={0};
- fd1 = open(FIFO_NAME1, O_RDONLY);
- fd2 = open(FIFO_NAME2, O_WRONLY);
- while(read(fd1, buf, MAX) != 0) {
- printf("read from client:%s\n", buf);
- fgets(buf, MAX, stdin);
- buf[strlen(buf)-1] = 0;
- write(fd2, buf, MAX);
- }
- return 0;
- }
编译并运行这个全双工通信的例子:
编译链接:
- ^_^[sunny@sunny-laptop ~/summer/fifo_rw1]96$ gcc fifo_client.c -o client
- ^_^[sunny@sunny-laptop ~/summer/fifo_rw1]97$ gcc fifo_server.c -o server
执行客户端(client):
- ^_^[sunny@sunny-laptop ~/summer/fifo_rw1]98$ ./client
- hello world //从键盘输入
- client read from server:hello who are you?
- I am sunny. //从键盘输入
- client read from server:Oh
- bye //从键盘输入
- client read from server:bye
- connect over,exit successfully!
- ^_^[sunny@sunny-laptop ~/summer/fifo_rw1]99$
执行服务器端(server):
- ^_^[sunny@sunny-laptop ~/summer/fifo_rw1]5$ ./server
- read from client:hello world
- hello who are you? //从键盘输入
- read from client:I am sunny.
- Oh //从键盘输入
- read from client:bye
- bye //从键盘输入ctrol+d
- ^_^[sunny@sunny-laptop ~/summer/fifo_rw1]6$
程序说明:这两个程序先执行client之后,再启动server(否则会发生一些问题,大家可以试验一下)。之后现在client端输入数据,转到server端发现从中读取了数据,紧接着在server端输入,就这样循环着,呵呵......
0
上一篇:通过管道和重定向实现linux管道命令(二)
下一篇:验证管道只能用于有亲缘关系的进程通信
相关热门文章
- Python 包管理工具解惑
- Qt学习笔记---信号与槽...
- 存在依赖关系的内核模块的编译...
- Linux内核与根文件系统的关系...
- Cisco VPP node关系图
- test123
- 编写安全代码——小心有符号数...
- 彻底搞定C语言指针详解-完整版...
- 使用openssl api进行加密解密...
- 一段自己打印自己的c程序...
- linux dhcp peizhi roc
- 关于Unix文件的软链接
- 求教这个命令什么意思,我是新...
- sed -e "/grep/d" 是什么意思...
- 谁能够帮我解决LINUX 2.6 10...
给主人留下些什么吧!~~
评论热议
0 0
- 有名管道(FIFO)实现无亲缘关系的客户服务器
- 有名管道(FIFO)实现无亲缘关系的客户服务器
- 无亲缘关系的客户与服务器
- 有名管道在无亲缘进程间的通信
- 有名管道(FIFO)的用法
- 有名管道FIFO的读写
- FIFO 有名管道的使用
- 有名管道FIFO的使用
- linux 有名管道(FIFO)
- linux 有名管道(FIFO)
- linux 有名管道(FIFO)
- linux 有名管道(FIFO)
- 有名管道FIFO的一个客户端输出
- linux 有名管道FIFO的一点理解
- 进程间的通信----有名管道fifo
- linux系统中的有名管道(FIFO)
- FIFO 有名管道
- 有名管道FIFO实例
- ADB Interface 驱动安装失效
- 向IPC进发
- NBUT1219 Time(打表,水题)
- Newtown Casino Hulk Slot Game Marvel Jackpot!(new town, newtoawn casino download, Newtown Casino, n)
- 通过管道和重定向实现linux管道命令(二)
- 有名管道(FIFO)实现无亲缘关系的客户服务器
- Android 下载 简单Dialog
- 验证管道只能用于有亲缘关系的进程通信
- 如何设置ntp出现漂移的问题
- 二进制位运算
- linux下支持的进程间通信方式
- leedcode_100. Same Tree
- tinker热修复 简介
- System V进程间通信—— 消息队列
原创粉丝点击
热门IT博客
热门问题
老师的惩罚
人脸识别
我在镇武司摸鱼那些年
重生之率土为王
我在大康的咸鱼生活
盘龙之生命进化
天生仙种
凡人之先天五行
春回大明朝
姑娘不必设防,我是瞎子
金蝉养殖吧
蝉的养殖方法
金蝉养殖基地
金蝉花的功效与作用
金蝉花多少钱一只
脱壳金蝉
金蝉北里
黄金蝉
金蝉止痒胶囊价格
金蝉花的价格
六翅金蝉
金蝉脱窍
金蝉口服液
金蝉玉叶
爆炒金蝉
金蝉茶宠
金蝉南里二手房
金蝉纹身
金蝉花的功效
金蝉皮
金蝉玉
金蝉花泡酒方法
金蝉草
刘海戏金蝉
金蝉花泡酒
六翼金蝉
金蝉花产地
以色列金蝎
金蝎地下金属探测器
金蝶社区
金蝶影院
金蝶k
金蝶云
金蝶反过账
金蝶云星空
金蝶云会计
金蝶k/3
金蝶商贸版
金蝶金斗云
金蝶供应链
金蝶代理商