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三个函数中有所处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值