有名管道FIFO的使用

对于有名管道FIFO,它是半双工的。类似于管道但是又不同于管道。它是一个单向数据流。更为重要的是,每个FIFO有一个路径名与之关联,从而允许无亲缘关系的进程访问同一个FIFO。
管道只能用于有一个共同祖先进程的各个进程之间。
FIFO由mkfifo函数创建。
#include<sys/types.h>
#include<sys/stat.h>
int mkfifo(const char *pathname,mode_t mode);
使用两个FIFO代替管道来编写客户—服务器的例子
#include<sys/stat.h>
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<fcntl.h>
#define FIFO1 "/tmp/fifo.1"
#define FIFO2 "/tmp/fifo.2"
#define FILE_MODE S_IFIFO|0666
#define MAXLINE 2000
void client(int ,int ),server(int,int);
 int main(int arg,char **argvc)
{
    int readfd,writefd;
    pid_t childpid;
    unlink(FIFO1);
    unlink(FIFO2);
    /*create two FIFO2;OK if they already exist*/
    if(mkfifo(FIFO1,FILE_MODE)<0)
    {
        printf("can't create %s\n",FIFO1);
        exit(1);
    }
    if(mkfifo(FIFO2,FILE_MODE)<0)
    {
        unlink(FIFO1);
        printf("cant't create %s\n",FIFO2);
        exit(1);
    }
    /*child*/
    if((childpid = fork())==0)
    {
        readfd = open(FIFO1,O_RDONLY,0);
        writefd = open(FIFO2,O_WRONLY,0);
        server(readfd,writefd);
        exit(0);
    }
    /*parent*/
    writefd = open(FIFO1,O_WRONLY,0);
    readfd= open(FIFO2,O_RDONLY,0);
    client(readfd,writefd);
    waitpid(childpid,NULL,0);
    close(readfd);
    close(writefd);
    unlink(FIFO1);
    unlink(FIFO2);
    exit(0);

}
void server(int readfd,int writefd)
{
    int fd;
    ssize_t n;
    char buff[MAXLINE+1];
    /*read pathname from IPC channel*/
    if((n = read(readfd,buff,MAXLINE))==0)
    {
        printf("It's an error,please exit");
        exit(1);
        }
    buff[n]='\0';               /*null terminate pathname*/
    if((fd = open(buff,O_RDONLY))<0)
    {
        /*error must tell client*/
        snprintf(buff + n,sizeof(buff) - n, ":can't open,%s\n",strerror(errno));
        n = strlen(buff);
        write(writefd,buff,n);
    }
    else
    {
        /*open succeed:copy file to IPC channel*/
        while((n = read(fd,buff,MAXLINE))>0)
        {
            write(writefd,buff,n);
            close(fd);
        }
    }
    
}

void client(int readfd,int writefd)
{
    size_t len;
    ssize_t n;
    char buff[MAXLINE];
    /*read pathname*/
    fgets(buff,MAXLINE,stdin);
    len = strlen(buff);/*fgets() guarantees null byte at end*/
    if(buff[len-1]=='\n')
        len--;   /*delete newline from fgets()*/
    /*write pathname to IPC channel*/
    write(writefd,buff,len);
    /*read from IPC,write to standard output*/
    while((n = read(readfd,buff,MAXLINE))>0)
        write(STDOUT_FILENO,buff,n);
    

}
(1)在这个函数中要注意前面两个宏定义#define FIFO1 “/tmp/fifo.1”
                                                    #define FIFO2 "/tmp/fifo.2"

如果tmp前面少了/ 的话在程序运行过程中就不会找到tmp,运行完can't create fifo.1就会结束。
(2)还有在程序中使用的一些 宏定义的标识符
如:O_RDONLY、O_WRONLY都包含在头文件 #include<fcntl.h>中
STDOUT_FILENO等文件描述符包含在#include<unistd.h>中;在unix系统调用中,标准输入描述字用stdin,标准输出用stdout,标准出错用stderr表示,但在一些调用函数,引用了STDIN_FILENO表示标准输入才,同样,标准出入用STDOUT_FILENO,标准出错用STDERR_FILENO.
他们的区别:
stdin等是FILE *类型,属于标准I/O,在<stdio.h>。
STDIN_FILENO等是文件描述符,是非负整数,一般定义为0, 1, 2,属于没有buffer的I/O,直接调用系统调用,在<unistd.h>。 
size_t 包含在头文件 #include<stdlib.h>
mkfifo()包含在头文件#include<sys/stat.h>
#define FILE_MODE   S_IFIFO|0666  指名创建一个有名管道且权限为0666.

你可能感兴趣的:(有名管道FIFO的使用)