ConnectNamedPipe and asio overlap ptr

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();
            //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);
}
+4
source share
1 answer

. IOCP . , pipe, CreateNamedPipeA boost::asio::windows::stream_handle ConnectNamedPipe.

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

All Articles