zoukankan      html  css  js  c++  java
  • 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] = '';     /* null terminate pathname */
    
        if ( (fd = open(buff, O_RDONLY)) < 0)
        {
            /* 4error: must tell client */
            // 打开失败则直接将错误信息写入管道
            snprintf(buff + n, sizeof(buff) - n, ": can't open, %s
    ", 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] == '
    ')
            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);
    }

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

  • 相关阅读:
    postgresql 2012 大会PPT下载 Joe
    Postgresql连接 Joe
    查看Postgresql的连接数 Joe
    greta使用
    CString GetFileDir(const CString& csFile)
    UnicodeToAnsi函数
    myeclipse优化方案
    bool CreatedMultipleDirectory( char* direct)
    LPWSTR GBK(LPCSTR plszUtf8, WCHAR* lpszGBK)
    真正整合资源的高手
  • 原文地址:https://www.cnblogs.com/fengkang1008/p/4721478.html
Copyright © 2011-2022 走看看