美文网首页Linux学习之路Linux读书笔记
APUE读书笔记-17高级进程通信(9)

APUE读书笔记-17高级进程通信(9)

作者: QuietHeart | 来源:发表于2020-08-13 18:07 被阅读0次

    接口定义

    我们定义如下的三个函数来发送和接收文件描述符号,在本节的后面,我们将会展示对于流和套接字的这三个函数的代码。

    如果进程(通常是服务进程)想要发送文件描述符号给另外一个进程,那么调用send_fd或者send_err。

    #include "apue.h"
    int send_fd(int fd, int fd_to_send);
    int send_err(int fd, int status, const char *errmsg);
    

    两者返回:如果成功返回0,如果错误返回1。

    函数send_fd通过fd代表的unix域的套接字或者stream pipe来发送文件描述符号"fd_to_send"。

    我们将要使用s-pipe来表示全双工的通信通道,这个通道可以采用streams pipe或者unix域套接字实现。

    send_err函数使用fd发送errmsg,并且fd后面接着的status状态值必须在范围1到255之间。

    进程(通常客户进程)如果等待接收文件描述符号则调用recv_fd。

    int recv_fd(int fd, ssize_t (*userfunc)(int, const void *, size_t));
    

    返回:如果成功返回文件描述符号,如果错误返回负数。

    客户进程调用recv_fd来接收一个文件描述符号。如果所有的过程成功(发送者调用send_fd),那么会返回一个非负数的文件描述符号作为函数的返回值。否则,返回值表示send_err发出的状态(在1到255区间的负数)。另外,如果服务进程发送一个错误的消息,那么客户进程的userfunc函数将会被调用来处理这个消息。userfunc函数的第一个参数是STDERR_FILENO,后面接着的是指向错误消息的指针以及它的长度。userfunc函数的返回值就是写入的字节数目或者表示错误时候的负数。一般来说客户进程会指定一个常用的write函数作为userfunc。

    接口实现策略

    我们自己实现了一个这三个函数所使用的协议。

    发送的时候

    • 发送文件描述符号时,send_fd发送两个字节的0,后面接着实际的文件描述符号。 (即 0-0-fd_to_send
    • 发送错误时,send_err发送错误消息errmsg,后面接着一个字节的0,然后是状态字节的绝对值(从1到255), (即 errmsg-0-errstatus )。

    如果发送文件描述符号,那么开始0实际就是null,所以相当于一个"空字符串+0+描述符号";而不发送文件描述符号相当于"错误消息字符串+状态绝对值"。

    接收的时候

    • 函数recv_fd读取s-pipe上所有内容直到遇到一个null字节,此刻读取到的字符都会被传递到调用者的userfunc中。

      此时,接收了 errmsg-0, 还剩下 errstatus ; 或 0, 还剩下 0-fd_to_send

    recv_fd的下一个字节就是状态字节,

    • 如果状态字节是0,那么会传递一个文件描述符号(此时是还剩下 0-fd_to_send 的情况);
    • 否则不会接收到文件描述符号(此时是还剩下 status 的情况)

    send_err函数

    函数send_err在写错误消息到s-pipe之后调用send_fd函数。如下所示:

    #include "apue.h"
    /*
     * Used when we had planned to send an fd using send_fd(),
     * but encountered an error instead. We send the error back
     * using the send_fd()/recv_fd() protocol.
     */
    int send_err(int fd, int errcode, const char *msg)
    {
        int     n;
    
        if ((n = strlen(msg)) > 0)
            if (writen(fd, msg, n) != n)    /* send the error message */
                return(-1);
    
        if (errcode >= 0)
            errcode = -1;   /* must be negative */
    
        if (send_fd(fd, errcode) < 0)
            return(-1);
    
        return(0);
    }
    

    下面将看到函数send_fd和recv_fd函数的实现。将文件描述符号通过基于流的管道进行传递。

    相关文章

      网友评论

        本文标题:APUE读书笔记-17高级进程通信(9)

        本文链接:https://www.haomeiwen.com/subject/byhwrktx.html