管道和FIFO(一)

管道是無名的,只能用於有血緣關係之間的進程通訊。FIFO正是爲了彌補這個缺陷而設計出來的。服務器

#include <unistd.h>設計

int pipe(int fd[2]);code

經過宏S_ISFIFO來肯定一個描述符或文件是不是FIFO,惟一參數是stat結構體的st_mode成員。server

下面一個例子:進程

父進程使用客戶端程序,經過標準輸入調用一個路徑名來,而後經過管道發送給子進程,子進程使用服務器程序,經過管道獲取這個路徑名,而後將這個文件內容經過管道再發送給客戶端。客戶端再將文件內容打印出來。ip

代碼:get


/*mainpipe.c*/
int main(int argc, char **argv)
{
    int pipe1[2],pipe2[2];
    pid_t childpid;

    pipe(pipe1);//創建兩個管道,管道1用於客戶端將路徑名發送給服務器端
    pipe(pipe2);//管道2用於將服務器端輸出內容發送給客戶端

    if ((childpid = fork()) == 0) {//子進程
        close(pipe1[1]);//關閉寫,只讀管道1
        close(pipe2[0]);//關閉讀,只寫管道2

        server(pipe1[0], pipe2[1]);//從第一個參數讀,第二個參數寫
        exit(0);
    }
/*parent*/
    close(pipe1[0]);
    close(pipe2[1]);

    client(pipe2[0], pipe1[1]);//從第一個參數讀,第二個參數寫

    waitpid(childpid, NULL, 0);
    exit(0);
}
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define MAXLINE 1000

/*從標準輸入讀取一個路徑名,將這個路徑名寫入一個管道里去
,再另一個管道讀取服務器端發送過來的內容,而後顯示在
標準輸出裏。第一個參數是讀取通道,第二個參數是寫入通道*/
//client.c
 void client(int readfd, int writefd)
{
    size_t len;
    ssize_t n;
    char buff[MAXLINE];

    fgets(buff, MAXLINE, stdin);//從標準輸入獲取一行,以換行符結尾的

    len = strlen(buff);
    if (buff[len-1] == '\n') 
        len--;//去除最後一個換行符
    write(writefd, buff, len);//寫入到第二個參數裏去

    while( (n = read(readfd, buff, MAXLINE)) > 0)//從第一個參數讀取,若是,
                                                //在服務器端這個管道關閉了,這裏將會返回0
        write(STDOUT_FILENO, buff, n);
}



#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <error.h>
#include <fcntl.h>
#include <errno.h>
#define MAXLINE 1000

/*這是個服務器程序,從第一個參數讀取路徑名,而後打開這個路徑名,
將這個路徑名文件內容輸入到第二個參數寫入通道去*/
//server.c
void server(int readfd, int writefd)
{
    int fd;
    ssize_t n;
    char buff[MAXLINE+1];

    if ( (n = read(readfd, buff, MAXLINE)) == 0) //從第一個參數讀取路徑名
        perror("end of file while reading pathname");
    buff[n] = '\0';給路徑名加一個結尾

    if ( (fd = open(buff,O_RDONLY)) < 0) {//打開路徑名
        snprintf(buff + n, sizeof(buff) - n, ":can't open, %s\n", strerror(errno));
       
       n = strlen(buff);
        write(writefd, buff, n);
    } else {
        while ( (n =read(fd, buff, MAXLINE)) > 0)//讀取路徑名那個文件內容
            write(writefd, buff, n);//將內容寫到第二個參數去
        close(fd);
    }
}
相關文章
相關標籤/搜索