【问题标题】:How can I turn either a Unix POSIX file descriptor or standard input Handle into a Socket?如何将 Unix POSIX 文件描述符或标准输入句柄转换为套接字?
【发布时间】:2012-07-19 10:12:46
【问题描述】:

inetdsystemd 类型的系统中,系统可以绑定一个套接字并使用已经存在的套接字启动应用程序,例如提供基于套接字的服务启动。我想在我的一个 Haskell 守护程序中利用此功能。

守护进程当前调用socketbindSocketlisten 来创建一个Socket 对象,我以后可以调用accept。要将其更改为 inetd 类型系统,我需要使用标准输入作为 Socket,但目前我能找到的只有 stdin :: HandlefdToHandle :: CInt -> Handle - 两者都不是我需要的。

我似乎找不到任何类型为Handle -> Socket 的东西,也找不到任何类似于stdin :: Socket 的东西。我能找到的最接近的是mkSocket,它是非常低级的,并且大多数其他语言(即Ruby)都提供了将文件描述符转换为套接字的调用,而无需指定各种其他参数。

【问题讨论】:

    标签: networking haskell posix inetd systemd


    【解决方案1】:

    C 应用程序可以拥有sd-daemon.h,它可以自动处理套接字传递。在 Haskell 中,这个文件必须手动模拟。

    您可以使用stdInput 获取stdin 文件描述符。当然也可以使用handleToFd 函数。由于您需要特定于 POSIX 的行为,但不能指望它在 Windows 上工作。

    一旦有了 FD,就别无选择,只能使用 mkSocket 函数。 Haskell 无法猜测你想要什么样的套接字,所以你必须指定它。你很可能想要:

    mkSocket fd AF_UNIX Stream defaultProtocol Listening
    

    请记住,这不一定是systemd 将文件描述符传递给您的应用程序的方式。您必须检查 LISTEN_FDSLISTEN_PID 环境变量以查看要使用的文件描述符以及您的工作是否甚至绑定套接字。代表默认套接字的默认文件描述符是 FD 3,而不是您假设的 FD 0。如果服务文件需要,systemd 还可能为您提供多个套接字供您使用。

    【讨论】:

    • 谢谢!从长远来看,我想我最终可能只是为 sd-daemon.h 写了一个 FFI,但这应该足以让我继续前进。一个简单的问题,为什么NotConnected 超过Listening?套接字最初是否未绑定并设置为由 systemd 侦听?调用mkSocket后是否需要将socket切换到监听模式?
    • 我将sd-daemon.c 中的代码解释错了。套接字确实处于侦听模式。
    • 好的,我终于让它工作了。原来 AF_INET6 是套接字系列,而不是我所期望的 AF_INET 或 AF_UNIX。我已经编辑了你的答案。
    【解决方案2】:

    MkSocket 的主要技巧是知道你有正确的参数。 sd-daemon.h 对此有所帮助。我从 systemd man page on sd_is_fifo 看到它使用 fstat 和 getsockname,code for sd_is_socket is in git here

    您可以使用包裹在unix package 中的fstat 来提供帮助

    getFdStatus :: Fd -> IO FileStatus
    
    isSocket :: FileStatus -> Bool
    

    Network 包(部分使用 Network.Socket.Internals)也使用 C getsockname 函数(帮助程序 withNewSockAddr 为答案分配正确的缓冲区)。这需要猜测“家庭”,或者只是为答案分配一个大缓冲区(来自 RFC 2553 的sockaddr_storage)。但是 Network 从 Socket 数据中获取套接字文件描述符。您可以从 Network 中提取代码并重新实现 sd-daemons.h 所做的检查。

    另外,getsockopt 代码可能已包装在 network-socket-options package 中。

    但似乎没有人按照您需要的方式将其组合在一起。奇怪。

    【讨论】:

      猜你喜欢
      • 2020-09-08
      • 2017-03-08
      • 1970-01-01
      • 2011-12-08
      • 1970-01-01
      • 2018-10-05
      • 1970-01-01
      • 1970-01-01
      • 2015-05-09
      相关资源
      最近更新 更多