ConnectNamedPipe et asio superposés ptr

J’ai nommé pipe server qui est écrit en utilisant asio de boost. Le serveur crée un canal nommé et les appels ConnectNamedPipe passant asio se superposent à lui. Le problème est que le gestionnaire d’achèvement transmis à asio overlapped n’est jamais appelé, cela appelle CreateFile côté client ne déclenchera pas le gestionnaire d’achèvement transmis à ConnectNamedPipe. Qu’est-ce que je fais mal?

Voici la liste complète des clients et des serveurs:

#define _WIN32_WINNT 0x0501 #include  #include  #include  #include  #include  #include  #include  #include  #include  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::ssortingng PIPE_NAME = "\\\\.\\pipe\\BC33AFC8-BA51-4DCD-9507-0234785D4F55_native_server_pipe"; class Server : public std::enable_shared_from_this { public: Server(){} ~Server(){} void Start() { mIoService = std::make_shared(); mWork = std::make_shared(*mIoService); mThread = std::make_shared( 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 mIoService; std::shared_ptr mWork; std::shared_ptr 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 s = std::make_shared(); 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); } 

J’ai trouvé le problème. Je n’ai pas associé de tuyau avec IOCP lui-même dans la partie serveur. Cela peut être fait en CreateNamedPipeA handle natif renvoyé par CreateNamedPipeA dans boost::asio::windows::stream_handle juste avant d’appeler ConnectNamedPipe .

 typedef boost::asio::windows::stream_handle StreamHandler; std::shared_ptr streamHandler = std::make_shared(*mIoService); streamHandle->assign(pipe);