簡體   English   中英

如何使用 Boost.Asio 和 Boost.Procees 在 Windows 的子進程中繼承套接字?

[英]How can I inherrit a socket in a child process on Windows using Boost.Asio and Boost.Procees?

我正在編寫一個多進程套接字服務器,在 Linux 上它工作得很好,但在 Windows 上它只是崩潰而沒有任何錯誤。 我相信這是因為它實際上並沒有正確繼承套接字文件描述符。

下面是我的代碼的精簡版本,它只打印子進程中的所有文件描述符。 在我的 windows VM 上,它會打印一個 FD 列表,但它從父進程傳遞的 FD 不在列表中,它高於列出的任何一個。

我找到了有關如何繼承套接字的 windows 文檔: https://docs.microsoft.com/en-us/windows/win32/sysinfo/handle-inheritance

我還發現 Boost.Process 具有此屬性,這表明默認情況下處理程序繼承的: https://www.boost.org/doc/libs/1_78_0/doc/html/boost/process/limit_handles.html

但目前尚不清楚為什么我的套接字沒有被繼承,以及如何處理它。

#include <stdio.h>
#include <string> 
#include <boost/asio.hpp>
#include <boost/process.hpp>
#include <boost/process/handles.hpp>


using boost::this_process::native_handle_type;
using namespace boost::asio;
using ip::tcp;

int main(int argc, char const *argv[])
{
    int port = 5923;
    if (argc == 2 && strcmp(argv[1], "--help")==0) {
        printf("%s [port]\n", argv[0]);
        return 0;
    } else if (argc == 3 && strcmp(argv[1], "--child")==0) {
        printf("child process\n");
        int fd = std::stoi(argv[2]);
        auto hds = boost::this_process::get_handles();
        for (auto h : hds) {
            std::cout << h << std::endl;
        }
        printf("got FD %d\n", fd);
        return 0;
    } else if (argc == 2)
    {
        port = std::stoi(argv[1]);
    }
    boost::asio::io_service io_service;
    tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v6(), port));
    while (1)
    {
        printf("waiting for clients\n");
        tcp::socket peersocket(io_service);
        acceptor.accept(peersocket);
        auto endpoint = peersocket.remote_endpoint();
        printf("Accepted new connection from a client %s:%d\n", endpoint.address(), endpoint.port());
        std::string fd = std::to_string(peersocket.release());
        std::cout << fd << std::endl;
        boost::process::spawn(argv[0], "--child", fd);
    }
    return 0;
}

好的,我找到了答案,它實際上是超級簡單的 EOF

Jk,我將把解決方案留給未來的我或其他迷失的靈魂。

您必須編寫一個“擴展”以使 Windows 繼承句柄。 https://www.boost.org/doc/libs/1_78_0/doc/html/boost_process/extend.html

windows_executor的屬性在這里解釋: windows_executor ://www.boost.org/doc/libs/1_78_0/doc/html/boost/process/extend/windows_executor.html

所以我們需要做的就是注冊一個on_setup擴展並將inherit_handles設置為true。 像這樣的東西:

struct do_inherit : boost::process::extend::handler
{
    template<typename Char, typename Sequence>
    void on_setup(ex::windows_executor<Char, Sequence> & exec)
    {
        std::cout << "windows setup" << std::endl;
        exec.inherit_handles = 1;
    }

    template<typename Sequence>
    void on_setup(ex::posix_executor<Sequence> & exec)
    {
        std::cout << "unix setup" << std::endl;
    }
};

有了這些現代技術,我們終於可以做inetd幾十年前所做的事情,但現在有了更多的模板 generics 和 Windows。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM