`

Unix 域套接字与描述符的传递

阅读更多
        在Unix 域套接字概述一节中介绍了什么是 Unix 及相关函数,本文将继续介绍 Unix 域套接字在进程间传递描述符的应用。
        在进程间传递打开的描述符时通常会采用如下两种方法:
        (1)fork 调用返回后,子进程自动共享父进程的所有打开的描述符。
        (2)exec 调用执行后,所有描述符通常保持打开状态不变。
        第一种方法中,进程先打开一个描述符,再调用 fork,之后父进程关闭这个描述符,子进程则处理该描述符。这样一个打开的描述符就从父进程传递到子进程。不过有时候可能想让子进程打开一个描述符并把他传递给父进程。
        使用 Unix 域套接字,可以从一个进程向任一其他进程传递打开的描述符,而无需这两个进程之间存在亲缘关系。这种技术要求首先在这两个进程之间创建一个 Unix 域套接字,然后使用 sendmsg 跨这个套接字发送一个特殊消息。该消息由内核来专门处理,会把打开的描述符从发送进程传递到接收进程。
        使用 Unix 域套接字在两个进程之间传递描述符涉及的步骤如下。
        (1)创建一个字节流或数据报的 Unix 域套接字。如果目标是让子进程将打开的描述符传递回父进程,则父进程可以预先调用 socketpair 函数创建一个可用于在父子进程之间交换描述符的流管道。如果进程间没有亲缘关系,则服务器进程必须先创建一个 Unix 域字节流套接字(也可以是 Unix 域数据报套接字,不过这没什么好处,而且数据报还存在被丢弃的可能性),然后 bind 一个路径名到该套接字,以允许客户进程 connect 到套接字,发送一个打开某个描述符的请求。
        (2)发送进程通过调用返回描述符的任一 Unix 函数(如 open、pipe、mkfifo、socket 和 accept,可以在进程之间传递的描述符不限类型)打开一个描述符。
        (3)发送进程创建一个 msghdr 结构,其中含有待传递的描述符。POSIX 规定描述符作为辅助数据(msghdr 结构的 msg_control 成员,见辅助数据)发送。发送进程调用 sendmsg 跨来自步骤 1 的 Unix 域套接字发送该描述符。至此,称这个描述符“在飞行中(in flight)”。即使发送进程在调用 sendmsg 之后但在接收进程调用 recvmsg 之前关闭了该描述符,对于接收进程它仍然保持打开状态。发送一个描述符会使该描述符的引用计数加一。
        (4)接收进程调用 recvmsg 在来自步骤 1 的 Unix 域套接字上接收这个描述符。这个描述符在接收进程中的描述符号不同于它在发送进程中的描述符号是正常的,因为传递一个描述符并不是传递一个描述符号,而是涉及在接收进程中创建一个新的描述符,该描述符和发送进程中飞行前的那个描述符指向内核中相同的文件表项。
分享到:
评论

相关推荐

    经由UNIX域套接字传送文件描述符所涉及的相关知识(自己整理)

    ### 经由UNIX域套接字传送文件描述符的关键知识点 #### 1. 前言:文件描述符传输的重要性 文件描述符是操作系统分配给已打开文件的唯一标识符,通常是一个非负整数。在进程间通信(IPC)中,能够直接传输文件描述符...

    unix domain socket传递描述符

    “工具”可能是指一些利用Unix域套接字和描述符传递的实用工具或库,例如libsocketcan用于CAN总线通信,或者某些进程间通信框架如ZeroMQ,它们可能在内部使用了Unix域套接字来高效地传递文件描述符。 总的来说,...

    C例子:Unix域数据报套接字通信

    在这个示例中,我们可能会看到如何定义并使用结构体sockaddr_un来表示Unix域套接字地址,以及如何处理文件描述符(file descriptor)和错误检查。学习这个例子可以帮助理解Unix域套接字的工作原理,以及如何在C语言...

    libancillary:使用 Unix 域套接字在进程之间传递文件描述符

    库辅助使用 Unix 域套接字在进程之间传递文件描述符克隆概述这个库为可以在 Unix 域套接字上完成的黑魔法提供了一个简单的接口,比如将文件描述符从一个进程传递到另一个进程。 它应该 100% 符合 Single Unix ...

    python-passfd:跨 UNIX 域套接字传递文件描述符的 Python 函数

    这个简单的扩展提供了两个函数来通过 UNIX 域套接字传递和接收文件描述符,使用 BSD-4.3+ sendmsg()和recvmsg()接口。 没有提供对sendmsg()和recvmsg()直接绑定,因为 API 不能很好地映射到 Python。 请注意,这仅...

    jnr-unixsocket:适用于Java的UNIX域套接字(AF_UNIX)

    jnr-unixsocket库还支持文件描述符传递,这是UNIX域套接字的一个强大特性。文件描述符传递允许进程之间直接交换已打开的文件、套接字或其他资源,进一步增强了IPC的能力。 此外,jnr-unixsocket库也考虑到了安全性...

    UNIX网络编程卷1:套接字联网API(第3版)源代码

    同时,还可能涉及套接字级别的控制消息(例如,SCM_RIGHTS用于传递文件描述符)。 6. **错误处理和调试**:通过源代码,读者可以学习到如何正确处理网络编程中常见的错误,如EINTR、ECONNREFUSED、ETIMEDOUT等,并...

    Unix Domain Sokcet

    - **资源管理**:Unix域套接字可以实现文件描述符的传递,这在网络套接字中是不可行的。 Unix域套接字的使用场景包括: - 进程间通信:如守护进程与用户界面的通信。 - 服务替换:在开发和测试环境中,可以用Unix域...

    LINUX进程间传递描述符.pdf

    在Linux操作系统中,...通过Unix域套接字和相关的系统调用,开发者可以实现复杂的进程间通信场景,特别是在需要共享文件描述符或套接字描述符的场合。理解并熟练运用这些技术对于编写高效的多进程应用程序至关重要。

    LINUX进程间传递描述符[收集].pdf

    总的来说,Linux下的进程间描述符传递利用了Unix域套接字和内核的特殊处理,通过`sendmsg`和`recvmsg`函数实现了描述符的安全转移。这种方法允许进程间共享文件描述符,极大地扩展了进程通信的能力,尤其是在需要...

    linux 多线程通信 socket

    2. 文件描述符传递:主线程通过共享内存或线程间函数(如`pthread_setspecific`和`pthread_getspecific`)将套接字文件描述符传递给其他工作线程。 3. 数据传输:工作线程通过接收到的套接字文件描述符进行读写操作...

    UNIX网络编程 UNIX网络编程 卷1:套接字联网API(第3版)

    《UNIX网络编程 卷1:套接字联网API(第3版)》是网络编程领域的一本经典著作,尤其在UNIX/Linux系统上有着广泛的影响力。这本书深入浅出地讲解了如何使用套接字API进行网络通信,对于学习C++编程语言的开发者来说,...

    Java网络编程--Unix域协议:概述

    虽然其他IPC机制如消息队列、共享内存、命名管道等也有各自的优势,但Unix域协议的接口兼容性使其在很多场景下成为首选,尤其是在本地高速通信和需要描述符传递的场合。 网络编程API标准IEEE POSIX 1003.1g(也称为...

    文件描述符1

    - UNIX域套接字传递:进程可以通过UNIX域套接字将一个打开的文件描述符传递给另一个进程,使得接收进程可以访问发送进程已经打开的文件。 4. 文件描述符的管理: - 文件描述符有固定的上限,可以通过`ulimit`命令...

    UNIX网络编程 卷1:套接字联网API(英文版•第3版) 源代码

    同时,讲解了套接字控制消息(如SCM_RIGHTS,用于传递文件描述符)的使用。 6. **错误处理与调试**:提供了处理网络编程中常见错误的方法,如EINTR、EWOULDBLOCK等,以及如何使用strerror_r获取错误信息。 7. **...

    《Unix网络编程卷1:套接字联网API》第三版配套源码

    10. **套接字API的高级特性**:如套接字对、文件描述符传递、SOCK_RAW等高级特性在源码中也有体现。 通过深入研究这些源码,你不仅能掌握Unix网络编程的基础,还能了解更高级的特性和最佳实践。实践是理解理论的...

    tiny-nix-ipc-最小包装器,用于通过文件描述符传递将套接字用作IPC-Rust开发

    UNIX / SOCK_SEQPACKET / CLOEXEC)进行套接字对,但是如果您要轮询(使用轮询,select,kqueue,epoll,类似mio的抽象等),当然可以使用FromRawFd使用AsRawFd获取fd所有发送/接收方法都允许文件描述符(fd)传递,...

    fd:在不同的OS进程之间传递Go文件描述符和连接

    服务器启动其自身的新副本并传递Unix域套接字名称 新副本开始从套接字读取数据 服务器通过套接字发送其状态,还发送要继承的网络连接数,然后使用fd.Put()发送这些连接 新服务器副本读取状态并使用fd.Get()继承...

Global site tag (gtag.js) - Google Analytics