转: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三个函数中有所处理。
转:sock_ev——linux平台socket事件框架(socket代理类) .的更多相关文章
- 转:sock_ev——linux平台socket事件框架(socket API的封装) .
把linux平台提供的有关socket操作的API进行封装是有必要的:基于stream操作的流程与基于dgram操作的流程略有不同,分别放在两个类中,但两者又有很多相似的操作,因此写一个基类,让其继承 ...
- 转:sock_ev——linux平台socket事件框架(event dispatcher) .
最近比较忙,好久没更新了:今天我们看一下事件的监听方式,在linux下面事件的监听方式有三种select.poll.epoll,性能上面epoll最高,如果仅是最多监听十多个描述符,用啥无所谓,如果是 ...
- 转:sock_ev——linux平台socket事件框架(基于字节流的测试程序) .
原文:http://blog.csdn.net/gdutliuyun827/article/details/8257186 由于工作与学习的需要,写了一个socket的事件处理框架,在公司写的已经使用 ...
- 转:sock_ev——linux平台socket事件框架(event loop) .
上一篇我们封装了三种事件监听方式,如果分别提供给客户端使用,有点不方便,也不利于统一管理:我们再封装一层EventLoop. /************************************ ...
- 转:sock_ev——linux平台socket事件框架(uri地址的解析) .
在第一篇中,已经说明,传递的socket地址采取以下形式: [cpp] view plaincopyprint?stream://192.168.2.10:8080 dgram://192.168 ...
- 转:sock_ev——linux平台socket事件框架(基于数据报的测试程序) .
上一篇已经做过注释,这一篇直接上代码 /******************************************************************************** ...
- 转:sock_ev——linux平台socket事件框架(logTrace) .
写代码要有调试log,采用syslog的输出:一般会输出到"/var/log/messages" /**************************************** ...
- AgileEAS.NET SOA 中间件平台.Net Socket通信框架-介绍
一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...
- AgileEAS.NET SOA 中间件平台.Net Socket通信框架-简单例子-实现简单的服务端客户端消息应答
一.AgileEAS.NET SOA中间件Socket/Tcp框架介绍 在文章AgileEAS.NET SOA 中间件平台Socket/Tcp通信框架介绍一文之中我们对AgileEAS.NET SOA ...
随机推荐
- noip2010初赛提高组 试题详解
转载自:https://blog.csdn.net/eirlys_north/article/details/52889970 一.单项选择题 1.与16进制数 A1.2等值的10进制数是 ( ) A ...
- HDU 4611 Balls Rearrangement 数学
Balls Rearrangement 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=4611 Description Bob has N balls ...
- HDU 4667 Building Fence(2013多校7 1002题 计算几何,凸包,圆和三角形)
Building Fence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)To ...
- ida sdk add_struc_member array
tid_t tid = get_struc_id ( "foo_type" ) ; struc_t * sptr = get_struc ( tid ); if ( sptr == ...
- 几个未公开的 DBCC 命令
http://blog.csdn.net/CathySun118/article/category/538610 https://ask.hellobi.com/blog/lyhabc/1612 1. ...
- VS2010下面Empty Project使用
VS2010下面Empty Project使用:1,添加代码HelloApp #include <afxwin.h> class CHelloApp:public CWinApp{publ ...
- svn 冲突
转载:http://blog.sina.com.cn/s/blog_65fd4c1e0100h2cg.html 1. 如何产生冲突 当开发人员A和开发人员B从版本库同时检出文档1.txt,而A和B同 ...
- Unity 面试题
一:什么是协同程序? 在主线程运行的同时开启另一段逻辑处理,来协助当前程序的执行,协程很像多线程,但是不是多线程,Unity的协程实在每帧结束之后去检测yield的条件是否满足. 二:Unity3d中 ...
- python接口自动化10-token登录
前言 有些登录不是用cookie来验证的,是用token参数来判断是否登录. token传参有两种一种是放在请求头里,本质上是跟cookie是一样的,只是换个单词而已:另外一种是在url请求参数里,这 ...
- java jdk查看源代码
事实上假设你安装了JDK的话,你就已经拥有了java api的源代码. 安装JDK文件夹下的src.zip文件就是java api的源代码. 比方:C:\Program Files\Java\jdk1 ...