前面分析了对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三个函数中有所处理。

转:sock_ev——linux平台socket事件框架(socket代理类) .的更多相关文章

  1. 转:sock_ev——linux平台socket事件框架(socket API的封装) .

    把linux平台提供的有关socket操作的API进行封装是有必要的:基于stream操作的流程与基于dgram操作的流程略有不同,分别放在两个类中,但两者又有很多相似的操作,因此写一个基类,让其继承 ...

  2. 转:sock_ev——linux平台socket事件框架(event dispatcher) .

    最近比较忙,好久没更新了:今天我们看一下事件的监听方式,在linux下面事件的监听方式有三种select.poll.epoll,性能上面epoll最高,如果仅是最多监听十多个描述符,用啥无所谓,如果是 ...

  3. 转:sock_ev——linux平台socket事件框架(基于字节流的测试程序) .

    原文:http://blog.csdn.net/gdutliuyun827/article/details/8257186 由于工作与学习的需要,写了一个socket的事件处理框架,在公司写的已经使用 ...

  4. 转:sock_ev——linux平台socket事件框架(event loop) .

    上一篇我们封装了三种事件监听方式,如果分别提供给客户端使用,有点不方便,也不利于统一管理:我们再封装一层EventLoop. /************************************ ...

  5. 转:sock_ev——linux平台socket事件框架(uri地址的解析) .

    在第一篇中,已经说明,传递的socket地址采取以下形式: [cpp] view plaincopyprint?stream://192.168.2.10:8080   dgram://192.168 ...

  6. 转:sock_ev——linux平台socket事件框架(基于数据报的测试程序) .

    上一篇已经做过注释,这一篇直接上代码 /******************************************************************************** ...

  7. 转:sock_ev——linux平台socket事件框架(logTrace) .

    写代码要有调试log,采用syslog的输出:一般会输出到"/var/log/messages" /**************************************** ...

  8. AgileEAS.NET SOA 中间件平台.Net Socket通信框架-介绍

    一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...

  9. AgileEAS.NET SOA 中间件平台.Net Socket通信框架-简单例子-实现简单的服务端客户端消息应答

    一.AgileEAS.NET SOA中间件Socket/Tcp框架介绍 在文章AgileEAS.NET SOA 中间件平台Socket/Tcp通信框架介绍一文之中我们对AgileEAS.NET SOA ...

随机推荐

  1. 使用SQL语句将数据库中的两个表合并成一张表

    select * into 新表名 from (select * from T1 union all select * from T2)  这个语句可以实现将合并的数据追加到一个新表中. 不合并重复数 ...

  2. python开发_pickle

    pickle模块使用的数据格式是python专用的,并且不同版本不向后兼容,同时也不能被其他语言说识别.要和其他语言交互,可以使用内置的json包使用pickle模块你可以把Python对象直接保存到 ...

  3. [转][Android] ListView中getView的原理+如何在ListView中放置多个item

      ListView 和 Adapter 的基础 工作原理: ListView 针对List中每个item,要求 adapter “给我一个视图” (getView). 一个新的视图被返回并显示 如果 ...

  4. linuxmint - setup - 搜狗输入法

    安装好linuxmint18后,官网下载搜狗输入法安装包安装.安装成功后,发现缺失部分界面,包括输入候选框,软件设置,fcitx设置都不太正常. 解决: 安装:fcitx-ui-classic 另: ...

  5. PHP自动加载下——PSR4

    1.先来介绍一下PSR规范 PHP-FIG,它的网站是:www.php-fig.org.就是这个联盟组织发明和创造了PSR规范,其中自动加载涉及其中两个规范,一个是PSR0,一个是PSR4, PSR0 ...

  6. Can a windows dll retrieve its own filename?

    http://stackoverflow.com/questions/2043/can-a-windows-dll-retrieve-its-own-filename A windows exe fi ...

  7. STM32 Hardware Development

    http://www.st.com/web/en/resource/technical/document/application_note/CD00164185.pdf AN2586 http://w ...

  8. Oracle数据库常用函数使用--持续更新中

    NVL函数.NVL( string1, replace_with).如果string1为NULL,则NVL函数返回replace_with的值,否则返回原来的值. INSTR函数.用于查找指定字符串是 ...

  9. jquery通过ajax提交form

    $.ajax({ type: "POST", url: "some.php", data: "name=John&location=Bosto ...

  10. Linux进程间通信—消息队列

    四.消息队列(Message Queue) 消息队列就是消息的一个链表,它允许一个或者多个进程向它写消息,一个或多个进程向它读消息.Linux维护了一个消息队列向量表:msgque,来表示系统中所有的 ...