使用unix域套接字传递描述符

时间:2009-11-24 05:56:43

标签: unix sockets network-programming

当我们想要将一个描述符从子节点传递给进程时,UNP V1(Unix网络编程V1)指定了一个复杂的过程,首先创建msghdr结构然后创建一些东西,等等。

为什么我们无法传递描述符作为正常数据意味着我们发送,通过unix域套接字recv其他数据? 我能够理解这个过程。请解释该书中给出的方法。

另外,在那本书中,在read_fd()函数中,他声明了union正确对齐msghdr结构。工会如何协调一致?以及为什么需要对齐?

2 个答案:

答案 0 :(得分:3)

  

为什么我们不能将描述符传递给   正常数据意味着我们发送,recv   通过unix域获取其他数据   插座?

因为打开的文件描述符无法作为字节流进行序列化。

虽然文件描述符实际上只是整数,但它们由内核(以每进程方式)映射到内核内部数据结构,这些结构描述了打开的'文件'(是'普通'文件?是一个块/字符特殊设备?它是某种网络套接字吗?是匿名管道吗?等等)。文件描述符传递的目标是在一些其他(可能不相关的)进程中创建一个新的文件描述符(可能带有一些其他整数值),该进程映射到与发送过程中的原始描述符相同的内核内部数据结构。 / p>

您必须经历的这些操作只是访问此功能的“API”(请注意,基于System V的Unix系统有一种基于STREAMS的文件描述符传递的替代方法,它使用不同的“API” )。我不知道历史,但我猜想传递“API”的BSD文件描述符的“复杂性”是由于将功能强加到预先存在的sendmsg(2)/recvmsg(2) API中。

  

联盟如何使其一致?为什么   需要对齐吗?

我没有在我面前实施UNP,但使用工会并不是唯一的方法。 Kragen Sitaker's portlisten example使用CMSG_ *宏而不是联合。我们的想法是确保<struct msghdr>.msg_control指向<struct cmsghdr>

答案 1 :(得分:-2)

如果没有该书的副本,我们很难向您解释书中给出的方法。

有几种通用技术可以将文件描述符从父进程传递到子进程。如果您在启动子项之前知道文件描述符编号

  • 将其放入命令行参数
  • 将其置于环境变量
  • 将它放在磁盘上的文件中(不是一个很好的选择)

如果您在启动子项后只知道文件描述符,那么将需要某种IPC:

  • 把它放在共享内存中
  • 通过套接字将其发送给孩子

听起来你正在阅读的书描述了最后一个选项。向儿童发送消息时,您可以自由选择要发送的数据的表示形式。如果您要发送文件描述符(整数)而没有其他信息,那么您可以自由选择任何表示形式。整数的ASCII表示可能是合适的,或者您可以发送表示32位整数的四个字节。

同样,很难猜到为什么书籍作者按照他们的方式做事,而不知道方法究竟是什么。