libuv封装pipe通信封装

#ifndef __CUVPIPEBASE__H_
#define __CUVPIPEBASE__H_
#include "UvBase.h"
#include <string>
class CUvPipeBase :
    public CUvBase
{
public:
    CUvPipeBase();
    virtual ~CUvPipeBase();

public:
    void SetPipeParam(std::string strPipeName, int iIpc);

protected:
    std::string mstrPipeName;
    int miIpc;//是否夸进程
};

#endif




#include "UvPipeBase.h"

CUvPipeBase::CUvPipeBase(){
    miIpc = 0;
}


CUvPipeBase::~CUvPipeBase(){
}

void CUvPipeBase::SetPipeParam(std::string strPipeName, int iIpc) {
    //win name like "\\\\?\\pipe\\uv-test"
    //linux name like "/tmp/uv-test-sock"

    mstrPipeName = strPipeName;
    miIpc = iIpc;
}

pipesvr如下

#ifndef __CUVPIEPESVR__H_
#define __CUVPIEPESVR__H_
#include "UvPipeBase.h"
class CUvPipeSvr : public CUvPipeBase{
public:
    CUvPipeSvr();
    virtual ~CUvPipeSvr();

public:
    static void ConnCb(uv_stream_t* pHandle, int iStatus);

protected:
    virtual int OnAccept(uv_pipe_t* pUvPipe) = 0;//TODO free pUvPipe
    virtual uv_pipe_t* AllocPipeCli();

protected:
    int Listen(int iBackLog = 5);

protected:
    uv_pipe_t* mpPipeSvr;
};

#endif



#include "UvPipeSvr.h"

CUvPipeSvr::CUvPipeSvr(){
    mpPipeSvr = nullptr;
}

CUvPipeSvr::~CUvPipeSvr(){
}

uv_pipe_t* CUvPipeSvr::AllocPipeCli() {
    uv_pipe_t* pPipeCli = (uv_pipe_t*)do_malloc(sizeof(uv_pipe_t));
    //Can Use Another Loop In SubClass
    uv_pipe_init(GetUvLoop(), pPipeCli, miIpc);
    return pPipeCli;
}

void CUvPipeSvr::ConnCb(uv_stream_t* pHandle, int iStatus) {
    CUvPipeSvr* pTcpSvr = (CUvPipeSvr*)uv_handle_get_data((uv_handle_t*)pHandle);
    if (nullptr != pTcpSvr) {
        if (iStatus < 0) {
            LOG_ERR("uv_listen error:%s", uv_strerror(-iStatus));
            return;
        }

        uv_pipe_t* pPipeCli = pTcpSvr->AllocPipeCli();
        ASSERT_RET(nullptr != pPipeCli);
        int iRet = uv_accept((uv_stream_t*)pTcpSvr->mpPipeSvr, (uv_stream_t*)pPipeCli);
        if (iRet < 0) {
            LOG_ERR("uv_accept error:%s", uv_strerror(-iRet));
            return;
        }

        if (pTcpSvr->OnAccept(pPipeCli) != 0) {
            DOFREE(pPipeCli);
        }
    }
}

int CUvPipeSvr::Listen(int iBackLog) {
    if (nullptr == mpUvLoop || nullptr == mpPipeSvr) {
        return 1;
    }

    /*uv_fs_t stUvFsReq;
    uv_fs_unlink(GetUvLoop(), &stUvFsReq, mstrPipeName.c_str(), nullptr);*/
    uv_handle_set_data((uv_handle_t*)mpPipeSvr, (void*)this);
    uv_pipe_init(GetUvLoop(), mpPipeSvr, miIpc);
    int iRet = uv_pipe_bind(mpPipeSvr, mstrPipeName.c_str());
    if (iRet < 0) {
        LOG_ERR("uv_pipe_bind error:%s %s", uv_strerror(-iRet), uv_err_name(iRet));
        return 1;
    }

    return uv_listen((uv_stream_t*)mpPipeSvr, iBackLog, CUvPipeSvr::ConnCb);
}

 

 

pipecli如下

#ifndef __CUVPIPECLI__H_
#define __CUVPIPECLI__H_
#include "UvPipeBase.h"
#include "UvMutex.h"
class CUvPipeCli : public CUvPipeBase
{
public:
    CUvPipeCli();
    virtual ~CUvPipeCli();

public:
    static void RecvCb(uv_stream_t* pHandle, ssize_t nRead, const uv_buf_t* pBuf);
    static void ConnCb(uv_connect_t* pReq, int iStatus);
    static void SendCb(uv_write_t* pReq, int iStatus);
    static void CloseCb(uv_handle_t* pHandle);
    static void NotifySend(uv_async_t* pHandle);

public:
    void SetPipeCli(uv_pipe_t* pPipeCli);
    int Connect();
    int Send(char* pData, ssize_t iLen);

protected:
    int Close();

private:
    int AfterConn();
    int Recv();
    int DoSend();
    void CleanSendQueue();

protected:
    virtual int OnRecv(ssize_t nRead, const uv_buf_t* pBuf) = 0;
    virtual int OnConn(int iStatus) = 0;
    virtual int OnClose() = 0;
    virtual int OnSend(int iStatus) = 0;

protected:
    uv_pipe_t* mpPipeCli;
    uv_connect_t* mpUvConn;

private:
    uv_async_t mstUvSendAsync;
    std::queue<uv_buf_t> mqueSendBuf;
    CUvMutex mcSendMutex;
    uv_write_t mstUvWriteReq;
    uv_buf_t mstWriteBuf;
};

#endif





#include "UvPipeCli.h"

CUvPipeCli::CUvPipeCli(){
}

CUvPipeCli::~CUvPipeCli(){
}

void CUvPipeCli::RecvCb(uv_stream_t* pHandle, ssize_t nRead, const uv_buf_t* pBuf) {
    CUvPipeCli* pPipeCli = (CUvPipeCli*)uv_handle_get_data((uv_handle_t*)pHandle);
    if (nullptr != pPipeCli) {
        if (nRead == 0) {
            if (!uv_is_active((uv_handle_t*)pPipeCli->mpPipeCli)) {
                LOG_ERR("Cli is Closed!");
            }

            return;
        }

        if (nRead < 0) {
            pPipeCli->Close();
            return;
        }
        else if (nRead > 0) {
            pPipeCli->OnRecv(nRead, pBuf);
        }
    }
}

void CUvPipeCli::SetPipeCli(uv_pipe_t* pPipeCli) {
    ASSERT_RET(nullptr != mpUvLoop);
    mpPipeCli = pPipeCli;
    uv_handle_set_data((uv_handle_t*)mpPipeCli, (void*)this);
    AfterConn();
}

int CUvPipeCli::AfterConn() {
    Recv();
    uv_handle_set_data((uv_handle_t*)&mstUvSendAsync, (void*)this);
    return uv_async_init(mpUvLoop, &mstUvSendAsync, CUvPipeCli::NotifySend);
}

void CUvPipeCli::ConnCb(uv_connect_t* pReq, int iStatus) {
    CUvPipeCli* pPipeCli = (CUvPipeCli*)uv_handle_get_data((uv_handle_t*)pReq);
    if (nullptr != pPipeCli) {
        if (iStatus >= 0) {
            pPipeCli->AfterConn();
        }

        pPipeCli->OnConn(iStatus);
        pPipeCli->DoSend();
    }
}

int CUvPipeCli::Connect() {
    if (nullptr == mpPipeCli || nullptr == mpUvLoop || nullptr == mpUvConn) {
        return 1;
    }

    uv_handle_set_data((uv_handle_t*)mpPipeCli, (void*)this);
    uv_pipe_init(GetUvLoop(), mpPipeCli, miIpc);

    uv_handle_set_data((uv_handle_t*)mpUvConn, (void*)this);
    uv_pipe_connect(mpUvConn, mpPipeCli, mstrPipeName.c_str(), CUvPipeCli::ConnCb);
    return 0;
}

int CUvPipeCli::Recv() {
    if (nullptr == mpPipeCli || nullptr == mpUvLoop) {
        return 1;
    }

    int iSockBufLen = (int)(mstUvBuf.iLen - mstUvBuf.iUse);
    uv_recv_buffer_size((uv_handle_t*)mpPipeCli, &iSockBufLen);
    return uv_read_start((uv_stream_t*)mpPipeCli, CUvBase::UvBufAlloc, CUvPipeCli::RecvCb);
}

void CUvPipeCli::SendCb(uv_write_t* pReq, int iStatus) {
    CUvPipeCli* pPipeCli = (CUvPipeCli*)uv_handle_get_data((uv_handle_t*)pReq);
    if (nullptr != pPipeCli)
    {
        pPipeCli->mcSendMutex.Lock();
        if (!pPipeCli->mqueSendBuf.empty()) {
            uv_buf_t stTmp = pPipeCli->mqueSendBuf.front();
            DOFREE(stTmp.base);
            pPipeCli->mqueSendBuf.pop();
        }
        pPipeCli->mcSendMutex.UnLock();

        pPipeCli->OnSend(iStatus);
        if (iStatus < 0) {
            if (iStatus == UV_ECANCELED) {
                return;
            }

            LOG_ERR("uv_write:%s", uv_strerror(-iStatus));
            pPipeCli->Close();
        }
        else
        {
            pPipeCli->DoSend();
        }
    }
}

void CUvPipeCli::NotifySend(uv_async_t* pHandle) {
    CUvPipeCli* pPipeCli = (CUvPipeCli*)uv_handle_get_data((uv_handle_t*)pHandle);
    if (nullptr != pPipeCli) {
        pPipeCli->DoSend();
    }
}

int CUvPipeCli::DoSend() {
    memset(&mstWriteBuf, 0, sizeof(mstWriteBuf));
    mcSendMutex.Lock();
    if (!mqueSendBuf.empty()) {
        uv_buf_t stTmp = mqueSendBuf.front();
        mstWriteBuf.base = stTmp.base;
        mstWriteBuf.len = stTmp.len;
    }
    mcSendMutex.UnLock();

    if (mstWriteBuf.len <= 0) {
        return 0;
    }

    uv_handle_set_data((uv_handle_t*)&mstUvWriteReq, (void*)this);
    return uv_write(&mstUvWriteReq, (uv_stream_t*)mpPipeCli, &mstWriteBuf, 1, CUvPipeCli::SendCb);
}

int CUvPipeCli::Send(char* pData, ssize_t iLen) {
    if (nullptr == pData || iLen <= 0 || nullptr == mpPipeCli || nullptr == mpUvLoop || uv_is_closing((uv_handle_t*)&mstUvWriteReq) != 0) {
        return 1;
    }

    uv_buf_t stTmp;
    stTmp.base = (char*)do_malloc(iLen);
    stTmp.len = (unsigned long)iLen;
    memcpy(stTmp.base, pData, iLen);
    mcSendMutex.Lock();
    mqueSendBuf.push(stTmp);
    mcSendMutex.UnLock();
    return uv_async_send(&mstUvSendAsync);
}

void CUvPipeCli::CleanSendQueue() {
    mcSendMutex.Lock();
    while (!mqueSendBuf.empty()) {
        uv_buf_t stTmp = mqueSendBuf.front();
        DOFREE(stTmp.base);
        mqueSendBuf.pop();
    }
    mcSendMutex.UnLock();
}

void CUvPipeCli::CloseCb(uv_handle_t* pHandle) {
    CUvPipeCli* pPipeCli = (CUvPipeCli*)uv_handle_get_data((uv_handle_t*)pHandle);
    if (nullptr != pPipeCli) {
        pPipeCli->OnClose();
    }
}

int CUvPipeCli::Close() {
    if (nullptr == mpPipeCli || nullptr == mpUvLoop || uv_is_closing((uv_handle_t*)mpPipeCli) != 0) {
        return 1;
    }

    if (uv_is_active((uv_handle_t*)&mstUvSendAsync) != 0) {
        uv_close((uv_handle_t*)&mstUvSendAsync, nullptr);
    }

    uv_close((uv_handle_t*)mpPipeCli, CUvPipeCli::CloseCb);
    CleanSendQueue();
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值