I try to use windows pipes with asio::windows::stream_handle but I get an ununderstood behaviour for me: client side don't catch transfered data, but server side don't launch a handler of async_write. My code is below. Client and Server are two differrent processes, their binaries are in the same directory.
Server:
class MessageProcessor
{
private:
HANDLE m_WindowsPipeHandle;
OVERLAPPED m_OverlapWin;
std::unique_ptr<boost::asio::windows::stream_handle> m_Pipe;
public:
MessageProcessor(boost::asio::io_context& asio_ctx, const std::string& pipe_name)
{
if (std::filesystem::exists(pipe_name))
{
std::filesystem::remove(pipe_name);
}
m_WindowsPipeHandle = CreateNamedPipe(
pipe_name.c_str(),
PIPE_ACCESS_OUTBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
1,
1,
INFINITE,
NULL);
if (m_WindowsPipeHandle == INVALID_HANDLE_VALUE)
{
assert(false && "Pipe");
exit(EXIT_FAILURE);
}
if (ConnectNamedPipe(m_WindowsPipeHandle, &m_OverlapWin) != 0)
{
assert(false && "Connect Pipe");
exit(EXIT_FAILURE);
}
std::this_thread::sleep_for(std::chrono::seconds(1));
m_Pipe = std::make_unique<boost::asio::windows::stream_handle>(asio_ctx, m_WindowsPipeHandle);
}
void AsyncWrite(const std::string& msg)
{
log("Launch async transfer", msg);
boost::asio::async_write(
*m_Pipe,
boost::asio::buffer(msg),
[](const boost::system::error_code& error, size_t bytes_transferred)
{
if (error)
{
log("Pipe transfer error", error);
}
else
{
log("Pipe transfer ok", bytes_transferred);
}
});
}
};
AsynWrite is called defered by asio::post via timer
Client:
class Pipe
{
private:
HANDLE win_handle;
std::unique_ptr<boost::asio::windows::stream_handle> pipe;
std::string read_buf;
std::fstream fs;
public:
Pipe()
{
fs.open("tester.txt", std::ios_base::out);
win_handle = CreateFile(
cfg::PipeName.c_str(),
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
if (win_handle == INVALID_HANDLE_VALUE)
{
assert(false && "Pipe Client");
exit(EXIT_FAILURE);
}
pipe = std::make_unique<boost::asio::windows::stream_handle>(ctx, win_handle);
}
void Run()
{
fs << "Run launch" << std::endl;
boost::asio::async_read(
*pipe,
boost::asio::buffer(read_buf),
[this](const boost::system::error_code& error, size_t bytes)
{
if (error)
{
fs << error << std::endl;
}
if (!read_buf.empty())
{
fs << "Readed str: " << read_buf << std::endl;
}
else
{
fs << "Empty buf!" << std::endl;
}
boost::asio::post(ctx, boost::bind(&Pipe::Run, this));
});
}
};
It writes 'Empty buf' always :(
May be who knows, why my server doesn't real transfer data via win pipe?