zoukankan      html  css  js  c++  java
  • 转:sock_ev——linux平台socket事件框架(socket代理类) .

    前面分析了对socket基本操作的封装,并按照数据的传送方式写了两个类,本篇将写一个代理类提供给库的使用者使用的类。

    /***************************************************************************************
    ****************************************************************************************
    * FILE      : socket.h
    * Description   : 
    *             
    * Copyright (c) 2012 by Liu Yanyun(E-mail:liuyun827@foxmail.com). All Rights Reserved.
    *            Without permission, shall not be used for any commercial purpose

    * History:
    * Version       Name            Date            Description
       0.1      Liu Yanyun      2012/12/11      Initial Version
       
    ****************************************************************************************
    ****************************************************************************************/ 
     
     
    #ifndef _SOCKET_H_  
    #define _SOCKET_H_  
     
    #include <stdio.h>  
    #include <string.h>  
    #include <stdint.h>  
    #include "sock_ev.h"  
     
    class EventLoop; 
    class CommBase; 
    class SockAddr; 
     
     
    /*==================================================================
    * Function  : Socket
    * Description   : Socket used for app, adapter CommBase
    ==================================================================*/ 
    class Socket 

    public: 
     
      /*==================================================================
      * Function    : Socket.create
      * Description : static function used for create Socket,
      * Return Value: Socket pointer
      ==================================================================*/ 
      static Socket* create(); 
     
      /*==================================================================
      * Function    : Socket.destroy
      * Description : static function used for destroy Socket created by Socket.create
      * Input Para  : sock_--socket pointer
      ==================================================================*/ 
      static void destroy(Socket* &sock_); 
     
      /*==================================================================
      * Function    : Socket.getFd
      * Description : get socket fd
      * Return Value: socket fd,if fd is not avaliable -1 is return
      ==================================================================*/ 
      int getFd(); 
     
      /*==================================================================
      * Function    : Socket.open
      * Description : open socket in server of unconnection-mode
      * Input Para  : socket address uri
      * Return Value: if success return true, or else false is return
      ==================================================================*/ 
      bool open(const char *uri_); 
     
      /*==================================================================
      * Function    : Socket.connect
      * Description : connection-mode client connect to server
      * Input Para  : socket address uri
      * Return Value: if success return true, or else false is return
      ==================================================================*/ 
      bool connect(const char *uri_); 
     
      /*==================================================================
      * Function    : Socket.accept
      * Description : connection-mode server accept client connection
      * Input Para  : sock_--stand for client socket pointer
      * Return Value: if success return true, or else false is return
      ==================================================================*/ 
      bool accept(Socket *sock_); 
     
      /*==================================================================
      * Function    : Socket.send
      * Description : send data
      * Input Para  : data_--data pointer
      * Input Para  : len_--data length
      * Return Value: the number of characters sent
      ==================================================================*/ 
      int send(void *data_,  
          uint32_t len_); 
     
      /*==================================================================
      * Function    : Socket.send
      * Description : send data
      * Input Para  : data_--data pointer
      * Input Para  : len_--data length
      * Input Para  : to_--the address of the target
      * Return Value: the number of characters sent
      ==================================================================*/ 
      int send(void *data_,  
          uint32_t len_,  
          const char *to_); 
     
      /*==================================================================
      * Function    : Socket.recv
      * Description : recv data
      * Input Para  : data_--data pointer
      * Input Para  : len_--data length
      * Return Value: the number of characters received
      ==================================================================*/ 
      int recv(void *data_,  
          uint32_t len_); 
     
      /*==================================================================
      * Function    : Socket.recv
      * Description : recv data
      * Input Para  : data_--data pointer
      * Input Para  : len_--data length
      * Input Para  : from_--the address of the source
      * Return Value: the number of characters received
      ==================================================================*/ 
      int recv(void *data_,  
          uint32_t len_, 
          char *from_); 
     
      /*==================================================================
      * Function    : Socket.getEvt
      * Description : get event type
      * Return Value: already register event
      ==================================================================*/ 
      EventType getEvt(); 
     
      /*==================================================================
      * Function    : Socket.processEvent
      * Description : process Event
      * Input Para  : evt_--event
      ==================================================================*/ 
      void processEvent(EventType evt_); 
     
      /*==================================================================
      * Function    : Socket.setCallBack
      * Description : set calback function
      ==================================================================*/ 
      void setCallBack(EventLoop *loop_, 
          EvCallBack cb_, 
          EventType evt_, 
          void *arg_); 
     
      /*==================================================================
      * Function    : Socket.clearCallBack
      * Description : clear calback function
      ==================================================================*/ 
      void clearCallBack(EventType evt_); 
     
    private: 
     
      EventType   evt; 
      CommBase   *comm; 
      SockAddr   *addr; 
      EventLoop  *loop; 
      EvCallBack  rdCb; 
      EvCallBack  wrCb; 
      void       *rdArg; 
      void       *wrArg; 
       
      // Disable copy construction and assignment.  
      Socket(); 
      virtual ~Socket(); 
      Socket(const Socket&); 
      const Socket &operator = (const Socket&); 
    }; 
     
    #endif /*_SOCKET_H_*/ 

    上面是头文件有比较详细的注释,通过函数名也可以看出函数的意义。

     /***************************************************************************************
    ****************************************************************************************
    * FILE      : socket.cc
    * Description   : 
    *             
    * Copyright (c) 2012 by Liu Yanyun(E-mail:liuyun827@foxmail.com). All Rights Reserved.
    *            Without permission, shall not be used for any commercial purpose

    * History:
    * Version       Name            Date            Description
       0.1      Liu Yanyun      2012/12/11      Initial Version
       
    ****************************************************************************************
    ****************************************************************************************/ 
     
     
    #include "socket.h"  
    #include "sock_ev.h"  
    #include "socket_addr.h"  
    #include "socket_base.h"  
     
    using namespace std; 
     
    Socket::Socket() 

      evt  = 0; 
      comm = NULL; 
      addr = NULL; 
      loop = NULL; 
      rdCb = NULL; 
      wrCb = NULL; 
      rdArg= NULL; 
      wrArg= NULL; 

     
    Socket::~Socket() 

      if(NULL != comm) delete comm; 
       
      if(NULL != addr) delete addr; 

     
    Socket* Socket::create() 

      Socket *sock = new Socket(); 
      if(NULL == sock) 
      { 
        logTrace("new Socket() failed"); 
        return NULL; 
      } 
     
      return sock; 

    void Socket::destroy(Socket* &sock_) 

      if(NULL != sock_) delete sock_; 
     
      sock_ = NULL; 

    int Socket::getFd() 

      return comm->getSockFd(); 

    bool Socket::open(const char *uri_) 

      addr = new SockAddr(uri_); 
      if(NULL == addr) 
      { 
        logTrace("new SockAddr(%s) failed", uri_); 
        return false; 
      } 
     
      if(!addr->parseUri()) 
      { 
        logTrace("parseUri() failed;uri:%s", uri_); 
        return false; 
      } 
       
      int type = addr->getType(); 
      if(SOCK_STREAM == type) 
      { 
        comm = new StreamSock(); 
      } 
      else if(SOCK_DGRAM == type) 
      { 
        comm = new DgramSock(); 
      } 
      else 
      { 
        logTrace("addr.type is invalid;type:%s", type); 
        return false; 
      } 
     
      if(NULL == comm) 
      { 
        logTrace("new StreamSock() failed"); 
        return false; 
      } 
       
      if(!comm->openSock(*addr)) 
      { 
        logTrace("StreamSock.openSock() failed"); 
        return false; 
      } 
     
      return true; 

    bool Socket::connect(const char *uri_) 

      addr = new SockAddr(uri_); 
      if(NULL == addr) 
      { 
        logTrace("new SockAddr(%s) failed", uri_); 
        return false; 
      } 
     
      if(!addr->parseUri()) 
      { 
        logTrace("parseUri() failed;uri:%s", uri_); 
        return false; 
      } 
       
      int type = addr->getType(); 
      if(SOCK_STREAM == type) 
      { 
        comm = new StreamSock(); 
      } 
      else if(SOCK_DGRAM == type) 
      { 
        comm = new DgramSock(); 
      } 
      else 
      { 
        logTrace("addr.type is invalid;type:%s", type); 
        return false; 
      } 
     
      if(NULL == comm) 
      { 
        logTrace("new StreamSock() failed"); 
        return false; 
      } 
       
      if(!comm->connectTo(*addr)) 
      { 
        logTrace("StreamSock.connectTo() failed"); 
        return false; 
      } 
     
      return true; 

    bool Socket::accept(Socket *sock_) 

      sock_->addr = new SockAddr(addr->getDomain(), addr->getType()); 
      if(NULL == sock_->addr) 
      { 
        logTrace("new SockAddr(%d, %d) failed", addr->getDomain(), addr->getType()); 
        return false; 
      } 
     
      int acceptFd = comm->acceptSock(*(sock_->addr)); 
      if(-1 == acceptFd) 
      { 
        logTrace("accetp connection is failed"); 
        return false; 
      } 
     
      int type = addr->getType(); 
      if(SOCK_STREAM == type) 
      { 
        sock_->comm = new StreamSock(); 
      } 
      else if(SOCK_DGRAM == type) 
      { 
        sock_->comm = new DgramSock(); 
      } 
      else 
      { 
        logTrace("addr.type is invalid;type:%s", type); 
        return false; 
      } 
     
      if(NULL == sock_->comm) 
      { 
        logTrace("new StreamSock() failed"); 
        return false; 
      } 
       
      sock_->comm->setSockFd(acceptFd); 
     
      return true; 
       

    int Socket::send(void *data_,  
        uint32_t len_) 

      return comm->sendData(data_, len_); 

    int Socket::send(void *data_,  
        uint32_t len_,  
        const char *to_) 

      SockAddr *tmpAddr = new SockAddr(to_); 
      if(NULL == tmpAddr) 
      { 
        logTrace("new SockAddr(%s) failed", to_); 
        return -1; 
      } 
     
      if(!tmpAddr->parseUri()) 
      { 
        logTrace("parseUri() failed;uri:%s", to_); 
        delete tmpAddr; 
        return false; 
      } 
     
      int sendLen = comm->sendData(data_, len_, *tmpAddr); 
     
      delete tmpAddr; 
     
      return sendLen; 

    int Socket::recv(void *data_,  
        uint32_t len_) 

      return comm->recvData(data_, len_); 

    int Socket::recv(void *data_,  
        uint32_t len_, 
        char *from_) 

      SockAddr *tmpAddr = new SockAddr(addr->getDomain(), addr->getType()); 
      if(NULL == tmpAddr) 
      { 
        logTrace("new SockAddr(%s) failed"); 
        return -1; 
      } 
     
      int sendLen = comm->recvData(data_, len_, *tmpAddr); 
     
      if(NULL != from_) 
      { 
        string tmpStr; 
        if(tmpAddr->toStr(tmpStr)) 
        { 
          sprintf(from_, "%s", tmpStr.c_str()); 
        } 
        else 
        { 
          sprintf(from_, "%s", "Invalid socket address string"); 
        } 
      } 
     
      delete tmpAddr; 
     
      return sendLen; 

    EventType Socket::getEvt() 

      return evt; 

    void Socket::processEvent(EventType evt_) 

      if(NULL != rdCb && evt_&evRead) 
      { 
        rdCb(loop, this, evRead, rdArg); 
      } 
      else if(NULL != wrCb && evt_&evWrite) 
      { 
        wrCb(loop, this, evWrite, wrArg); 
      } 
      else 
      { 
        logTrace("eventType:%d;reCb:%p,wrCb:%p", evt_, rdCb, wrCb); 
      } 

     
    void Socket::setCallBack(EventLoop *loop_,  
        EvCallBack cb_, 
        EventType evt_, 
        void *arg_) 

      loop = loop_; 
       
      if(evt_& evRead) 
      { 
        evt |= evRead; 
        rdCb = cb_; 
        rdArg= arg_; 
      } 
     
      if(evt_& evWrite) 
      { 
        evt |= evWrite; 
        wrCb = cb_; 
        wrArg= arg_; 
      } 
     

     
    void Socket::clearCallBack(EventType evt_) 

      if(evt_&evRead) 
      { 
        evt &= ~evRead; 
        rdCb = NULL; 
        rdArg= NULL; 
      } 
     
      if(evt_&evWrite) 
      { 
        evt &= ~evRead; 
        wrCb = NULL; 
        wrArg= NULL; 
      } 
     
      if(0 == evt) 
      { 
        loop = NULL; 
      } 

    基本上就是对前篇中封装的两个类的调用,字节流与数据包的区分在open、connect、accept三个函数中有所处理。

  • 相关阅读:
    跨域问题
    Django缓存机制
    Django Reat Framework --- 版本控制
    Hellow!
    回忆
    突然看见新评论通知
    [退役前的小声bbbbbbbbbbbbbbbbbbbbbb]
    【题解】【CQOI2018】解锁屏幕(玄学优化)
    solution
    1009-自闭++
  • 原文地址:https://www.cnblogs.com/skyofbitbit/p/3672909.html
Copyright © 2011-2022 走看看