转: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 ...
随机推荐
- 使用SQL语句将数据库中的两个表合并成一张表
select * into 新表名 from (select * from T1 union all select * from T2) 这个语句可以实现将合并的数据追加到一个新表中. 不合并重复数 ...
- python开发_pickle
pickle模块使用的数据格式是python专用的,并且不同版本不向后兼容,同时也不能被其他语言说识别.要和其他语言交互,可以使用内置的json包使用pickle模块你可以把Python对象直接保存到 ...
- [转][Android] ListView中getView的原理+如何在ListView中放置多个item
ListView 和 Adapter 的基础 工作原理: ListView 针对List中每个item,要求 adapter “给我一个视图” (getView). 一个新的视图被返回并显示 如果 ...
- linuxmint - setup - 搜狗输入法
安装好linuxmint18后,官网下载搜狗输入法安装包安装.安装成功后,发现缺失部分界面,包括输入候选框,软件设置,fcitx设置都不太正常. 解决: 安装:fcitx-ui-classic 另: ...
- PHP自动加载下——PSR4
1.先来介绍一下PSR规范 PHP-FIG,它的网站是:www.php-fig.org.就是这个联盟组织发明和创造了PSR规范,其中自动加载涉及其中两个规范,一个是PSR0,一个是PSR4, PSR0 ...
- 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 ...
- STM32 Hardware Development
http://www.st.com/web/en/resource/technical/document/application_note/CD00164185.pdf AN2586 http://w ...
- Oracle数据库常用函数使用--持续更新中
NVL函数.NVL( string1, replace_with).如果string1为NULL,则NVL函数返回replace_with的值,否则返回原来的值. INSTR函数.用于查找指定字符串是 ...
- jquery通过ajax提交form
$.ajax({ type: "POST", url: "some.php", data: "name=John&location=Bosto ...
- Linux进程间通信—消息队列
四.消息队列(Message Queue) 消息队列就是消息的一个链表,它允许一个或者多个进程向它写消息,一个或多个进程向它读消息.Linux维护了一个消息队列向量表:msgque,来表示系统中所有的 ...