简体   繁体   中英

Connect with an already created named pipe with boost

I'm looking in to using third party libraries for IPC communication using named pipes on Windows . I've been using the Win32 API for this for the last few years. I was interested in replacing my implementation with a tried and true open source library.

I noticed that boost::process has an implementation of an async_pipe which would allow me to use it with boost::asio which would be really helpful for my application.

What I'm trying to do is create the named pipe on the server, which is a C# application. Once the pipe has been created, connect to it with a client using the boost::process::async_pipe .

The problem I'm having is I don't see an API in boost::process that would allow me to connect with an already created named pipe . The constructors for async_pipe create the pipe instead of connecting to an already created pipe .

Below is the code I'm currently using in the client which is erroneously creating the pipe

boost::asio::io_context ctx;
std::vector<char> buffer( 8196, 0 );

boost::process::async_pipe pipe{ ctx, R"(\\.\pipe\TestPipe)" }; 

boost::asio::async_read( pipe, boost::asio::buffer( buffer ),
    [ &buffer ]( const boost::system::error_code& ec, std::size_t size )
    {
        if ( ec )
            std::cout << "Error: " << ec.message( ) << '\n';
        else
        {
            std::string message{ std::begin( buffer ), std::begin( buffer ) + size };
            std::cout << "Received message: " << message << '\n';
        }
    } );

ctx.run( );

I'm unsure if I can use boost::process to achieve what I want. I'm wondering if there is a way I could use CreateFileW to connect with the named pipe and then pass the HANDLE to async_pipe but I haven't found any documentation regarding that.

Question

How can I connect with an already created named pipe using boost

OK, so I was going about it the wrong way. After reading this issue on Github Link I realized I needed to use a stream_handle instead. Note, the pipe must be opened in OVERLAPPED mode for this to work.

Creating the stream_handle

static boost::asio::windows::stream_handle OpenPipe( io_context& context )
{
    constexpr const wchar_t* pipeName{ LR"(\\.\pipe\TestPipe)" };
    return { context, CreateFileW( pipeName,
                                   GENERIC_READ | GENERIC_WRITE,
                                   0, nullptr,
                                   OPEN_EXISTING,
                                   FILE_FLAG_OVERLAPPED,
                                   nullptr ) };
}

Once the stream_handle is created you can use the async functions it provides for communication.

Using the stream_handle

std::vector<char> buffer( 8196, 0 );
pipe.async_read_some( boost::asio::buffer( buffer ), 
    [ &buffer ]( auto ec, auto size ) { } );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM