- 浏览: 142402 次
文章分类
最新评论
在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 域套接字上接收这个描述符。这个描述符在接收进程中的描述符号不同于它在发送进程中的描述符号是正常的,因为传递一个描述符并不是传递一个描述符号,而是涉及在接收进程中创建一个新的描述符,该描述符和发送进程中飞行前的那个描述符指向内核中相同的文件表项。
在进程间传递打开的描述符时通常会采用如下两种方法:
(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 域套接字概述
2019-03-12 22:48 982Unix 域协议并不是一个实际的协议族,而是在 ... -
kqueue 接口
2019-03-06 00:47 698kqueue 接口是 ... -
辅助数据
2019-02-28 00:40 693辅助数据(a ... -
recv/send 和 recvmsg/sendmsg 函数
2019-01-22 00:40 1585recv 和 send ... -
inetd 守护进程介绍
2019-01-09 21:51 1061在 4.3 BSD 系统之前,很多网络服务都是 ... -
主机名与 IP 地址的转换(续)
2018-12-25 00:37 960在主机名与 IP 地址的转换一节中提到的 ge ... -
主机名与 IP 地址的转换
2018-11-14 00:20 2335在网络编程中,尽管大部分情况下操作的都是 IP ... -
SCTP 事件通知
2018-02-08 03:49 996SCTP 提供了多种可用的通知,用户可经由这些通知追踪 ... -
SCTP 套接字选项
2018-02-04 09:35 1704在获取和设置套接 ... -
SCTP 套接字编程基础函数
2018-02-04 10:08 1062SCTP 服务器可以使 ... -
SCTP 套接字编程基础概念
2018-01-18 00:10 566SCTP 套接字分为一到一套接字和一到多套接字。提供一 ... -
UDP套接字编程基础
2018-01-14 10:37 576下图显示了使用 UDP 套接字编写客户/服务器程序时的 ... -
通用套接字选项
2018-01-02 00:46 555在获取和设置套接 ... -
获取和设置套接字选项
2017-12-29 08:21 445下面几种方法可用 ... -
I/O 复用之 poll 函数
2017-12-27 00:20 429poll 函数提供的功能与 select 类似,不过在 ... -
I/O 复用之select 函数
2017-12-12 00:32 519select 函数允许进 ... -
Unix 5 种 IO 模型概述
2017-11-19 01:44 308Unix 下有 5 种可用 ... -
套接字创建、连接和关闭函数
2017-08-13 17:16 671下图是一对 TCP 客户与服务器进程之间发生的一些典型 ... -
字节转换和填充函数
2017-08-06 01:09 433网络编程中,为保证发送协议栈和接收协议栈就如 32 位 ... -
IPv4 和 IPv6 的套接字地址结构
2017-08-01 21:03 742大多数套接字函数 ...
相关推荐
### 经由UNIX域套接字传送文件描述符的关键知识点 #### 1. 前言:文件描述符传输的重要性 文件描述符是操作系统分配给已打开文件的唯一标识符,通常是一个非负整数。在进程间通信(IPC)中,能够直接传输文件描述符...
“工具”可能是指一些利用Unix域套接字和描述符传递的实用工具或库,例如libsocketcan用于CAN总线通信,或者某些进程间通信框架如ZeroMQ,它们可能在内部使用了Unix域套接字来高效地传递文件描述符。 总的来说,...
在这个示例中,我们可能会看到如何定义并使用结构体sockaddr_un来表示Unix域套接字地址,以及如何处理文件描述符(file descriptor)和错误检查。学习这个例子可以帮助理解Unix域套接字的工作原理,以及如何在C语言...
库辅助使用 Unix 域套接字在进程之间传递文件描述符克隆概述这个库为可以在 Unix 域套接字上完成的黑魔法提供了一个简单的接口,比如将文件描述符从一个进程传递到另一个进程。 它应该 100% 符合 Single Unix ...
这个简单的扩展提供了两个函数来通过 UNIX 域套接字传递和接收文件描述符,使用 BSD-4.3+ sendmsg()和recvmsg()接口。 没有提供对sendmsg()和recvmsg()直接绑定,因为 API 不能很好地映射到 Python。 请注意,这仅...
jnr-unixsocket库还支持文件描述符传递,这是UNIX域套接字的一个强大特性。文件描述符传递允许进程之间直接交换已打开的文件、套接字或其他资源,进一步增强了IPC的能力。 此外,jnr-unixsocket库也考虑到了安全性...
同时,还可能涉及套接字级别的控制消息(例如,SCM_RIGHTS用于传递文件描述符)。 6. **错误处理和调试**:通过源代码,读者可以学习到如何正确处理网络编程中常见的错误,如EINTR、ECONNREFUSED、ETIMEDOUT等,并...
- **资源管理**:Unix域套接字可以实现文件描述符的传递,这在网络套接字中是不可行的。 Unix域套接字的使用场景包括: - 进程间通信:如守护进程与用户界面的通信。 - 服务替换:在开发和测试环境中,可以用Unix域...
在Linux操作系统中,...通过Unix域套接字和相关的系统调用,开发者可以实现复杂的进程间通信场景,特别是在需要共享文件描述符或套接字描述符的场合。理解并熟练运用这些技术对于编写高效的多进程应用程序至关重要。
总的来说,Linux下的进程间描述符传递利用了Unix域套接字和内核的特殊处理,通过`sendmsg`和`recvmsg`函数实现了描述符的安全转移。这种方法允许进程间共享文件描述符,极大地扩展了进程通信的能力,尤其是在需要...
2. 文件描述符传递:主线程通过共享内存或线程间函数(如`pthread_setspecific`和`pthread_getspecific`)将套接字文件描述符传递给其他工作线程。 3. 数据传输:工作线程通过接收到的套接字文件描述符进行读写操作...
《UNIX网络编程 卷1:套接字联网API(第3版)》是网络编程领域的一本经典著作,尤其在UNIX/Linux系统上有着广泛的影响力。这本书深入浅出地讲解了如何使用套接字API进行网络通信,对于学习C++编程语言的开发者来说,...
虽然其他IPC机制如消息队列、共享内存、命名管道等也有各自的优势,但Unix域协议的接口兼容性使其在很多场景下成为首选,尤其是在本地高速通信和需要描述符传递的场合。 网络编程API标准IEEE POSIX 1003.1g(也称为...
- UNIX域套接字传递:进程可以通过UNIX域套接字将一个打开的文件描述符传递给另一个进程,使得接收进程可以访问发送进程已经打开的文件。 4. 文件描述符的管理: - 文件描述符有固定的上限,可以通过`ulimit`命令...
同时,讲解了套接字控制消息(如SCM_RIGHTS,用于传递文件描述符)的使用。 6. **错误处理与调试**:提供了处理网络编程中常见错误的方法,如EINTR、EWOULDBLOCK等,以及如何使用strerror_r获取错误信息。 7. **...
10. **套接字API的高级特性**:如套接字对、文件描述符传递、SOCK_RAW等高级特性在源码中也有体现。 通过深入研究这些源码,你不仅能掌握Unix网络编程的基础,还能了解更高级的特性和最佳实践。实践是理解理论的...
UNIX / SOCK_SEQPACKET / CLOEXEC)进行套接字对,但是如果您要轮询(使用轮询,select,kqueue,epoll,类似mio的抽象等),当然可以使用FromRawFd使用AsRawFd获取fd所有发送/接收方法都允许文件描述符(fd)传递,...
服务器启动其自身的新副本并传递Unix域套接字名称 新副本开始从套接字读取数据 服务器通过套接字发送其状态,还发送要继承的网络连接数,然后使用fd.Put()发送这些连接 新服务器副本读取状态并使用fd.Get()继承...