转: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 ...
随机推荐
- iOS开发系列--通讯录、蓝牙、
iOS开发过程中有时候难免会使用iOS内置的一些应用软件和服务,例如QQ通讯录.微信电话本会使用iOS的通讯录,一些第三方软件会在应用内发送短信等.今天将和大家一起学习如何使用系统应用.使用系统服务: ...
- BFC与hasLayout
BFC与hasLayout都是CSS布局上的概念. 几个月前在微博上才了解什么是BFC,算是对布局有点初步的了解. hasLayout则是IE6.7产生许多bug的根源. 一.BFC Floats, ...
- STM32 USB VBUS 监控
OTG_FS general core configuration register (OTG_FS_GCCFG) Bit 21 NOVBUSSENS: VBUS sensing disable op ...
- 修改gnome-shell扩展“Applications Menu”的菜单区域宽度。
sudo打开 /usr/share/gnome-shell/extensions/apps-menu@gnome-shell-extensions.gcampax.github.com/extensi ...
- 【微信小程序】view顶部固定或底部固定 + scroll-view中的元素view也可以使用position:fixed;固定选中元素位置
1.顶端固定核心代码如下: <view class="page__hd" style="position:fixed; top:0;width: 750rpx;&q ...
- 如何使用花生壳 发布WCF服务 进行外网访问 z
http://www.cnblogs.com/wanglg/p/5375230.html 当我们发布WCF服务的时候,可以直接通过服务器的域名或者IP进行. 但是如果仅仅是通过花生壳进行域名解析,需要 ...
- python笔记6-%u60A0和\u60a0类似unicode解码
前言 有时候从接口的返回值里面获取到的是类似"%u4E0A%u6D77%u60A0%u60A0"这种格式的编码,不是python里面的unicode编码. python里面的uni ...
- [Android Pro] Android系统手机端抓包方法 和 通过File查看应用程序流量
adb shellcat proc/uid_stat/%uid%/tcp_snd proc/uid_stat/%uid%/tcp_rcv ------------------------------ ...
- Linux进程间通信—管道
Linux下的进程通信手段基本上是从UNIX平台上的进程通信手段继承而来的.而对UNIX发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间 ...
- java学习笔记11--集合总结
java学习笔记系列: java学习笔记10--泛型总结 java学习笔记9--内部类总结 java学习笔记8--接口总结 java学习笔记7--抽象类与抽象方法 java学习笔记6--类的继承.Ob ...