Linux学习之路Linux读书笔记

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

2020-08-13  本文已影响0人  QuietHeart

接口定义

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

如果进程(通常是服务进程)想要发送文件描述符号给另外一个进程,那么调用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。

接口实现策略

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

发送的时候

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

接收的时候

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

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函数的实现。将文件描述符号通过基于流的管道进行传递。

上一篇下一篇

猜你喜欢

热点阅读