分享

有名管道及其实例1

 XeonGate 2020-08-17

https://blog.csdn.net/derkampf/article/details/60762854

一.介绍
前面的无名管道博文中,我们看到了创建两个管道可以实现进程间的全双工通信,那么同样也可以创建两个FIFO(有名管道)来实现不同进程间的全双工通信。
1.为什么引入有名管道?
我们通常所说的管道为无名管道或者匿名管道,管道没有名字,因此,只能在有亲缘关系的进程间(父子进程)实现通信,有名管道的出现突破了该限制,它是一个设备文件,它提供一个路径名与FIFO关联,即使进程与创建FIFO的进程不存在亲缘关系,只要可以访问这个路径也可以实现通信。
2.创建有名管道
mknod/mkfifo
shell中的创建方式

mknod 名字 pipemkfifo 名字

函数创建方式

(1)int mknod(const char *path, mode_t mode, dev_t dev);参数mode的选择Name      DescriptionS_IFIFO   FIFO-specialS_IFCHR   Character-special (non-portable)S_IFDIR   Directory (non-portable)S_IFBLK   Block-special (non-portable)S_IFREG   Regular (non-portable)If  mode  is  not S_IFIFO or dev is not 0, the behavior of mknod() is unspecified.举例:mknod("/tmp/fifo", S_IFIFO | 0666, 0)(2)int mkfifo(const char *pathname, mode_t mode);mkfifo()  makes  a  FIFO  special  file with name pathname.  mode specifies  the  FIFO's  permissions.所以只需要填写管道的权限就型举例mkfifo("/tmp/fifo", 0666);

3.使用有名管道
与无名管道的使用方法基本相同,只是需要先调用open函数将其打开。因为有名管道终究是在硬盘上的文件,而无名管道只是存在内存上的特殊文件。
注意open()的阻塞情况
1.以只写方式打开,阻塞直到有读方式打开管道
open(“/tmp/fifo”, O_WRONLY);
2.以只读方式打开,阻塞直到有写方式打开管道
open(“/tmp/fifo”, O_RDONLY);
3.同时读写方式打开,一定不阻塞。
open(“/tmp/fifo”, O_RDWR);

二.代码演示
1.server.c

#include"utili.h"int main(){    char sendbuf[MAX_MSG_LEN];    char recvbuf[MAX_MSG_LEN];    int res = mkfifo(FIFO_WRITE, 0666);    if(res == -1)    {        perror("mkfifo WRITE");        exit(EXIT_FAILURE);    }    //以只写方式打开,会阻塞到有读方式打开管道    int wfd = open(FIFO_WRITE, O_WRONLY);    if(wfd == -1)    {        perror("open WRITE");        exit(EXIT_FAILURE);    }    //以只读方式打开,会阻塞到有写方式打开管道    int rfd = open(FIFO_READ, O_RDONLY);    if(rfd == -1)    {        perror("open READ");        exit(EXIT_FAILURE);    }    while(1)    {        printf("Ser:>");        scanf("%s", sendbuf);        if(strcmp(sendbuf, "quit") == 0)        {             close(wfd);             unlink(FIFO_WRITE);             close(rfd);             exit(EXIT_SUCCESS);        }        write(wfd, sendbuf, strlen(sendbuf)+1);        read(rfd, recvbuf, MAX_MSG_LEN);        printf("Cli:>%s\n", recvbuf);    }}

2.client.c

#include"utili.h"int main(){    char recvbuf[MAX_MSG_LEN];    char sendbuf[MAX_MSG_LEN];    int wfd, rfd;    int res = mkfifo(FIFO_READ, 0666);    if(res == -1)    {        perror("mkfifo READ");        exit(EXIT_FAILURE);    }    //server的写对应client读    rfd = open(FIFO_WRITE, O_RDONLY);    if(rfd == -1)    {        perror("open READ");        exit(EXIT_FAILURE);    }    wfd = open(FIFO_READ, O_WRONLY);    if(wfd == -1)    {        perror("open WRITE");        exit(EXIT_FAILURE);    }    while(1)    {        read(rfd, recvbuf, MAX_MSG_LEN);        printf("Ser:>%s\n", recvbuf);        printf("Cli:>");        scanf("%s", sendbuf);        if(strcmp(sendbuf, "quit") == 0)        {             close(rfd);             unlink(FIFO_READ);             close(wfd);             exit(EXIT_SUCCESS);        }        write(wfd, sendbuf, strlen(sendbuf)+1);    }}

3.公共头文件
utili.h

#ifndef _UTILI_H_#define _UTILI_H_#include<stdio.h>#include<unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include<stdlib.h>#include<string.h>#define FIFO_READ "readfifo"#define FIFO_WRITE "writefifo"#define MAX_MSG_LEN 256#endif

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多