Unix IPC之pipe

pipe创建函数:

#include <unistd.h>

/* Create a one-way communication channel (pipe).
   If successful, two file descriptors are stored in PIPEDES;
   bytes written on PIPEDES[1] can be read from PIPEDES[0].
   Returns 0 if successful, -1 if not.  */
int pipe (int __pipedes[2]);

下面是一个测试实例,有些未说明函数,如Pipe,是pipe的一个包裹函数,二者参数及用法一致,仅仅是在包裹函数中添加了出错信息。

void client(int, int);
void server(int, int);

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

    Pipe(pipe1);    /* create two pipes */
    Pipe(pipe2);

    if ( (childpid = Fork()) == 0)          /* child */
    {
        Close(pipe1[1]);
        Close(pipe2[0]);

        server(pipe1[0], pipe2[1]); // 子线程作为服务器端
        exit(0);
    }
    /* 4parent */
    Close(pipe1[0]);
    Close(pipe2[1]);

    client(pipe2[0], pipe1[1]);

    Waitpid(childpid, NULL, 0);     /* wait for child to terminate */
    exit(0);
}
/**
 * 从客户端读取文件名,打开文件并将文件内容返回给客户端
 * @param readfd  管道读描述符
 * @param writefd 管道写描述符
 */
void server(int readfd, int writefd)
{
    int     fd;
    ssize_t n;
    char    buff[MAXLINE + 1];

    /* 4read pathname from IPC channel */
    if ( (n = Read(readfd, buff, MAXLINE)) == 0)
        err_quit("end-of-file while reading pathname");

    buff[n] = '\0';     /* null terminate pathname */

    if ( (fd = open(buff, O_RDONLY)) < 0)
    {
        /* 4error: must tell client */
        // 打开失败则直接将错误信息写入管道
        snprintf(buff + n, sizeof(buff) - n, ": can't open, %s\n", strerror(errno));
        n = strlen(buff);
        Write(writefd, buff, n);

    }
    else
    {
        /* 4open succeeded: copy file to IPC channel */
        while ( (n = Read(fd, buff, MAXLINE)) > 0)
            Write(writefd, buff, n);
        Close(fd);
    }
}

/**
 * 将键盘输入数据发送给服务器,并将服务器的回复信息显示在屏幕
 * @param readfd  管道读描述符
 * @param writefd 管道写描述符
 */
void client(int readfd, int writefd)
{
    size_t  len;
    ssize_t n;
    char    buff[MAXLINE];

    /* 4read pathname */
    Fgets(buff, MAXLINE, stdin); // 从键盘获取输入信息
    len = strlen(buff);     /* fgets() guarantees null byte at end */
    if (buff[len - 1] == '\n')
        len--;              /* delete newline from fgets() */

    /* 4write pathname to IPC channel */
    Write(writefd, buff, len); // 写入管道

    /* 4read from IPC, write to standard output */
    while ( (n = Read(readfd, buff, MAXLINE)) > 0)
        Write(STDOUT_FILENO, buff, n);
}

以上测试实例实现了一个如下的客户-服务器:

posted @ 2015-08-11 16:48  指上弹兵赵小括  阅读(884)  评论(0编辑  收藏  举报