I called the pipe server, which is written using boost asio. The server creates a named pipe and calls ConnectNamedPipe, passing it asio overlapped ptr. The problem is that the completion handler passed to asio overlapped is never called, that is, it calls CreateFile on the client side, it will not start the completion handler passed to ConnectNamedPipe. What am I doing wrong?
Here is the complete list of clients and server:
#define _WIN32_WINNT 0x0501
#include <string>
#include <functional>
#include <thread>
#include <boost/system/error_code.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/asio/windows/overlapped_ptr.hpp>
#include <boost/bind.hpp>
#include <tchar.h>
#include <Windows.h>
static const uint32_t PIPE_OUTPUT_BUFFER_RESERVED_SIZE_BYTES = 50 * 1024;
static const uint32_t PIPE_INPUT_BUFFER_RESERVED_SIZE_BYTES = 50 * 1024;
static const std::string PIPE_NAME = "\\\\.\\pipe\\BC33AFC8-BA51-4DCD-9507-0234785D4F55_native_server_pipe";
class Server
: public std::enable_shared_from_this<Server>
{
public:
Server(){}
~Server(){}
void Start()
{
mIoService = std::make_shared<boost::asio::io_service>();
mWork = std::make_shared<boost::asio::io_service::work>(*mIoService);
mThread = std::make_shared<std::thread>(
boost::bind(&boost::asio::io_service::run, mIoService));
mIoService->post(boost::bind(&Server::Accept, shared_from_this()));
}
void Accept()
{
mPipe = CreateNamedPipeA(
PIPE_NAME.c_str(),
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS,
PIPE_UNLIMITED_INSTANCES,
PIPE_OUTPUT_BUFFER_RESERVED_SIZE_BYTES,
PIPE_INPUT_BUFFER_RESERVED_SIZE_BYTES,
0,
nullptr);
if (mPipe == INVALID_HANDLE_VALUE)
{
DWORD err = GetLastError();
return;
}
boost::asio::windows::overlapped_ptr overlappedPtr(*mIoService,
std::bind(&Server::OnClientConnected, this, std::placeholders::_1, std::placeholders::_2));
OVERLAPPED* overlapped = overlappedPtr.get();
BOOL ok = ConnectNamedPipe(mPipe, overlapped);
DWORD lastError = GetLastError();
if (!ok && lastError != ERROR_IO_PENDING)
{
boost::system::error_code ec(lastError,
boost::asio::error::get_system_category());
overlappedPtr.complete(ec, 0);
}
else
{
overlappedPtr.release();
}
}
void OnClientConnected(
const boost::system::error_code& ec,
size_t bytesTransferred)
{
int a = 0;
a++;
}
private:
HANDLE mPipe;
std::shared_ptr<boost::asio::io_service> mIoService;
std::shared_ptr<boost::asio::io_service::work> mWork;
std::shared_ptr<std::thread> mThread;
};
class Client
{
public:
void Connect()
{
HANDLE hPipe = CreateFileA(
PIPE_NAME.c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
nullptr,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
nullptr
);
if (hPipe == INVALID_HANDLE_VALUE)
{
DWORD err = GetLastError();
if (err != ERROR_PIPE_BUSY)
{
return;
}
return;
}
}
};
std::shared_ptr<Server> s = std::make_shared<Server>();
Client c;
int CALLBACK WinMain(
_In_ HINSTANCE hInstance,
_In_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nCmdShow
)
{
s->Start();
Sleep(10000);
c.Connect();
Sleep(10000);
}
source
share