4
나는 boost asio를 사용하여 작성된 파이프 서버를 명명했습니다. 서버는 명명 된 파이프를 만들고 ConnectedPipe를 호출하여 asio overlapping ptr을 전달합니다. 문제는 클라이언트 측에서 CreateFile을 호출하면 ConnectNamedPipe에 전달 된 완료 핸들러가 트리거되지 않으므로 겹쳐진 asio에 전달 된 완료 핸들러가 호출되지 않는다는 것입니다. 내가 도대체 뭘 잘못하고있는 겁니까?ConnectNamedPipe와 asio overlappped ptr
#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();
//LOG(Error, "Failed create pipe: " << mPipeName << ", error: " << err);
return;
}
//LOG(Trace, "Pipe: " << mPipeName << " created successfully");
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)
{
// The operation completed immediately, so a completion notification needs
// to be posted. When complete() is called, ownership of the OVERLAPPED-
// derived object passes to the io_service.
boost::system::error_code ec(lastError,
boost::asio::error::get_system_category());
overlappedPtr.complete(ec, 0);
}
else
{
// The operation was successfully initiated, so ownership of the
// OVERLAPPED-derived object has passed to the io_service.
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)
{
/*LOG(Error, "Failed create pipe: " << mPipeName << ", error: " << err);
mOnConnected(nullptr);*/
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);
}
Server :: Start 메서드에서 스레드 전에 만든 io_service :: work 개체가 있습니다. – iendgame