转:sock_ev——linux平台socket事件框架(socket API的封装) .
把linux平台提供的有关socket操作的API进行封装是有必要的;基于stream操作的流程与基于dgram操作的流程略有不同,分别放在两个类中,但两者又有很多相似的操作,因此写一个基类,让其继承自这个基类;基类起名为:CommBase,操作stream与dgram两个类分别起名为:StreamSock、DgramSock;
/***************************************************************************************
****************************************************************************************
* FILE : socket_base.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/06 Initial Version
****************************************************************************************
****************************************************************************************/
#ifndef _SOCKET_BASE_H_
#define _SOCKET_BASE_H_
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <string>
class SockAddr;
/*==================================================================
* Function : CommBase
* Description : socket base class
==================================================================*/
class CommBase
{
public:
/*==================================================================
* Function : CommBase
* Description : construction function
==================================================================*/
CommBase();
/*==================================================================
* Function : CommBase
* Description : Destructor function
==================================================================*/
virtual ~CommBase();
/*==================================================================
* Function : CommBase.getSockFd
* Description : get socket fd
* Return Value: socket fd
==================================================================*/
int getSockFd();
/*==================================================================
* Function : CommBase.setSockFd
* Description : set socket fd
* Input Para : socket fd
* Return Value: void
==================================================================*/
void setSockFd(int fd);
/*==================================================================
* Function : CommBase.openSock
* Description : for stream (socket->bind->listen);for dgram(socket->bind)
* Input Para : socket address
* Return Value: if success return true, or else false is return
==================================================================*/
virtual bool openSock(SockAddr &addr_) = 0;
/*==================================================================
* Function : CommBase.acceptSock
* Description : used for server accept client connection
* Input Para : addr_--socket address
* Output Para : addr_--client address
* Return Value: if success return client fd, or else -1 is return
==================================================================*/
int acceptSock(SockAddr &addr_);
/*==================================================================
* Function : CommBase.connectTo
* Description : used for client to connect to server
* Input Para : socket address
* Return Value: if success return client fd, or else -1 is return
==================================================================*/
bool connectTo(SockAddr &addr_);
/*==================================================================
* Function : CommBase.sendData
* Description : send data
* Input Para : data_--data buf pointer
* Input Para : len_--data buf length
* Return Value: success send length
==================================================================*/
virtual int sendData(void *data_,
uint32_t len_);
/*==================================================================
* Function : CommBase.sendData
* Description : send data
* Input Para : data_--data buf pointer
* Input Para : len_--data buf length
* Input Para : addr_--address
* Return Value: success send length
==================================================================*/
virtual int sendData(void *data_,
uint32_t len_,
SockAddr &addr_);
/*==================================================================
* Function : CommBase.recvData
* Description : recv data
* Input Para : data_--data buf pointer
* Input Para : len_--data buf length
* Return Value: success recv length
==================================================================*/
virtual int recvData(void *data_,
uint32_t len_);
/*==================================================================
* Function : CommBase.recvData
* Description : recv data
* Input Para : data_--data buf pointer
* Input Para : len_--data buf length
* Input Para : addr_--address
* Return Value: success recv length
==================================================================*/
virtual int recvData(void *data_,
uint32_t len_,
SockAddr &addr_);
/*==================================================================
* Function : CommBase.enableSockReuse
* Description : enable socket address reuse
* Return Value: if success return true, or else false is return
==================================================================*/
bool enableSockReuse();
/*==================================================================
* Function : CommBase.setSendBufSize
* Description : set send buffer size
* Input Para : size_--buffer size
* Return Value: if success return true, or else false is return
==================================================================*/
bool setSendBufSize(uint32_t size_);
/*==================================================================
* Function : CommBase.setRecvBufSize
* Description : set recv buffer size
* Input Para : size_--buffer size
* Return Value: if success return true, or else false is return
==================================================================*/
bool setRecvBufSize(uint32_t size_);
/*==================================================================
* Function : CommBase.getSendBufSize
* Description : get send buffer size
* Return Value: if success return buffer size, or else -1 is return
==================================================================*/
int getSendBufSize();
/*==================================================================
* Function : CommBase.getRecvBufSize
* Description : get recv buffer size
* Return Value: if success return buffer size, or else -1 is return
==================================================================*/
int getRecvBufSize();
protected:
//socket fd
int sockFd;
private:
// Disable copy construction and assignment.
CommBase(const CommBase&);
const CommBase &operator = (const CommBase&);
};
/*==================================================================
* Function : StreamSock
* Description : Stream Socket class
==================================================================*/
class StreamSock : public CommBase
{
public:
/*==================================================================
* Function : StreamSock
* Description : construction function
==================================================================*/
StreamSock();
/*==================================================================
* Function : StreamSock
* Description : Destructor function
==================================================================*/
virtual ~StreamSock();
/*==================================================================
* Function : StreamSock
* Description : Please reference to CommBase
==================================================================*/
bool openSock(SockAddr &addr_);
/*==================================================================
* Function : StreamSock
* Description : Please reference to CommBase
==================================================================*/
int sendData(void *data_,
uint32_t len_);
/*==================================================================
* Function : StreamSock
* Description : Please reference to CommBase
==================================================================*/
int recvData(void *data_,
uint32_t len_);
};
/*==================================================================
* Function : DgramSock
* Description : Dgram Socket class
==================================================================*/
class DgramSock : public CommBase
{
public:
/*==================================================================
* Function : DgramSock
* Description : construction function
==================================================================*/
DgramSock();
/*==================================================================
* Function : StreamSock
* Description : Destructor function
==================================================================*/
virtual ~DgramSock();
/*==================================================================
* Function : StreamSock
* Description : Please reference to CommBase
==================================================================*/
bool openSock(SockAddr &addr_);
/*==================================================================
* Function : StreamSock
* Description : Please reference to CommBase
==================================================================*/
int sendData(void *data_,
uint32_t len_,
SockAddr &addr_);
/*==================================================================
* Function : StreamSock
* Description : Please reference to CommBase
==================================================================*/
int recvData(void *data_,
uint32_t len_,
SockAddr &addr_);
};
/#endif /*_SOCKET_BASE_H_*/
L28:尽量使用类型声明方式,而不是包含头文件
通过上面的函数声明可以看出,有关socket地址的参数统一为我们前一节中介绍的,SockAddr
#include "socket_base.h"
#include "socket_addr.h"
#include "log_trace.h"
#include <string>
using namespace std;
CommBase::CommBase()
{
sockFd = -1;
}
CommBase::~CommBase()
{
close(sockFd);
sockFd = -1;
}
int CommBase::getSockFd()
{
return sockFd;
}
void CommBase::setSockFd(int fd)
{
sockFd = fd;
}
int CommBase::acceptSock(SockAddr &addr_)
{
struct sockaddr *sockAddr = addr_.getAddr();
socklen_t addrLen = addr_.getSockLen();
int connFd = accept(sockFd, sockAddr, &addrLen);
if(-1 == connFd)
{
logTrace("%m");
}
return connFd;
}
bool CommBase::connectTo(SockAddr &addr_)
{
sockFd = socket(addr_.getDomain(), addr_.getType(), 0);
if( -1 == sockFd)
{
logTrace("%m");
return false;
}
const struct sockaddr *sockAddr = addr_.getAddr();
if(NULL == sockAddr)
{
logTrace("");
return false;
}
int rc = connect(sockFd, sockAddr, addr_.getSockLen());
if(-1 == rc)
{
logTrace("%m");
return false;
}
return true;
}
int CommBase::sendData(void *data_,
uint32_t len_)
{
logTrace("you can't use this method");
return -1;
}
int CommBase::sendData(void *data_,
uint32_t len_,
SockAddr &addr_)
{
logTrace("you can't use this method");
return -1;
}
int CommBase::recvData(void *data_,
uint32_t len_)
{
logTrace("you can't use this method");
return -1;
}
int CommBase::recvData(void *data_,
uint32_t len_,
SockAddr &addr_)
{
logTrace("you can't use this method");
return -1;
}
bool CommBase::enableSockReuse()
{
int flag = 1;
int rc = setsockopt (sockFd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof (flag));
if(0 != rc)
{
logTrace("%m");
}
return (0 == rc);
}
bool CommBase::setSendBufSize(uint32_t size)
{
int rc = setsockopt(sockFd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
if(0 != rc)
{
logTrace("%m");
}
return (0 == rc);
}
bool CommBase::setRecvBufSize(uint32_t size)
{
int rc = setsockopt(sockFd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
if(0 != rc)
{
logTrace("%m");
}
return (0 == rc);
}
int CommBase::getSendBufSize()
{
int size;
socklen_t len = sizeof(size);
int rc = getsockopt(sockFd, SOL_SOCKET, SO_SNDBUF, &size, &len );
if(0 != rc)
{
logTrace("%m");
return -1;
}
return size;
}
int CommBase::getRecvBufSize()
{
int size;
socklen_t len = sizeof(size);
int rc = getsockopt(sockFd, SOL_SOCKET, SO_RCVBUF, &size, &len );
if(0 != rc)
{
logTrace("%m");
return -1;
}
return size;
}
StreamSock::StreamSock()
{
//do nothing
}
StreamSock::~StreamSock()
{
//do nothing
}
bool StreamSock::openSock(SockAddr &addr_)
{
sockFd = socket(addr_.getDomain(), addr_.getType(), 0);
if( -1 == sockFd)
{
logTrace("%m");
return false;
}
enableSockReuse();
const struct sockaddr *sockAddr = addr_.getAddr();
if(NULL == sockAddr)
{
logTrace("");
return false;
}
int ret = bind(sockFd, sockAddr, addr_.getSockLen());
if(0 != ret)
{
logTrace("%m");
return false;
}
ret = listen(sockFd, 32);
if(0 != ret)
{
logTrace("%m");
return false;
}
return true;
}
int StreamSock::sendData(void *data_,
uint32_t len_)
{
int sendLen = 0;
do
{
sendLen = send(sockFd, data_, len_, 0);
}while(-1 == sendLen && EINTR == errno);
if(sendLen <= 0)
{
logTrace("%m");
}
return sendLen;
}
int StreamSock::recvData(void *data_,
uint32_t len_)
{
int recvLen = 0;
do
{
recvLen = recv(sockFd, data_, len_, 0);
}while(-1 == recvLen && EINTR == errno);
if(recvLen <= 0)
{
logTrace("%m");
}
return recvLen;
}
DgramSock::DgramSock()
{
//do nothing
}
DgramSock::~DgramSock()
{
//do nothing
}
bool DgramSock::openSock(SockAddr &addr_)
{
sockFd = socket(addr_.getDomain(), addr_.getType(), 0);
if( -1 == sockFd)
{
logTrace("%m");
return false;
}
const struct sockaddr *sockAddr = addr_.getAddr();
if(NULL == sockAddr)
{
logTrace("");
return false;
}
int ret = bind(sockFd, sockAddr, addr_.getSockLen());
if(0 != ret)
{
logTrace("%m");
return false;
}
return true;
}
int DgramSock::sendData(void *data_,
uint32_t len_,
SockAddr &addr_)
{
const struct sockaddr *sockAddr = addr_.getAddr();
if(NULL == sockAddr)
{
logTrace("");
return false;
}
int sendLen = 0;
do
{
sendLen = sendto(sockFd, data_, len_, 0, sockAddr, addr_.getSockLen());
}while(-1 == sendLen && EINTR == errno);
if(sendLen <= 0)
{
logTrace("%m");
}
return sendLen;
}
int DgramSock::recvData(void *data_,
uint32_t len_,
SockAddr &addr_)
{
struct sockaddr *sockAddr = addr_.getAddr();
socklen_t addrLen = addr_.getSockLen();
int recvLen = 0;
do
{
recvLen = recvfrom(sockFd, data_, len_, 0, sockAddr, &addrLen);
}while(-1 == recvLen && EINTR == errno);
if(recvLen <= 0)
{
logTrace("%m");
}
return recvLen;
}
上面的都是最简单的socket调用,不多说明!
转:sock_ev——linux平台socket事件框架(socket API的封装) .的更多相关文章
- 转:sock_ev——linux平台socket事件框架(socket代理类) .
前面分析了对socket基本操作的封装,并按照数据的传送方式写了两个类,本篇将写一个代理类提供给库的使用者使用的类. /**************************************** ...
- 转: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" /**************************************** ...
- 笔记整理--Linux平台MYSQL的C语言
Linux平台MYSQL的C语言API全列表 - 第三只眼的专栏 - 博客频道 - CSDN.NET - Google Chrome (2013/8/18 22:28:58) Linux平台MYS ...
- AgileEAS.NET SOA 中间件平台.Net Socket通信框架-介绍
一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...
随机推荐
- Miller-Rabin算法 codevs 1702 素数判定 2
转载自:http://www.dxmtb.com/blog/miller-rabbin/ 普通的素数测试我们有O(√ n)的试除算法.事实上,我们有O(slog³n)的算法. 定理一:假如p是质数,且 ...
- 洛谷P4009 汽车加油行驶问题
题目描述 给定一个 N \times NN×N 的方形网格,设其左上角为起点◎,坐标(1,1)(1,1),XX 轴向右为正, YY 轴向下为正,每个方格边长为 11 ,如图所示. 一辆汽车从起点◎出发 ...
- ExtJs2.0学习系列(12)--Ext.TreePanel之第一式
今天开始,我们就开始一起学习TreePanel了,道个歉,上篇的代码很乱阿. 我总是喜欢用最简单的例子开始,去理解最基本的使用方法,减少对i后面高级使用的干扰! TreePanel是继承自Panel, ...
- Caused by: java.net.UnknownHostException: localhost.localdomain: localhost.localdomain的问题解决
在hosts文件增加如下配置即可,下面的方法适合上面提示的错误,无论是Tomcat问题还是MongoDB等等的问题都可以完美解决. vi /etc/hosts 127.0.0.1 localhost ...
- Python模块之: configobj(转)
原来也有写过一篇文章Python模块之: ConfigParser 用来解析INI文件,但是在使用过程中存在一些问题.比如:1,不能区分大小写.2,重新写入的ini文件不能保留原有INI文件的注释.3 ...
- POJ 3384 Feng Shui (半平面交)
Feng Shui Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 3743 Accepted: 1150 Speci ...
- 升/降压转换器 (Buck-boost)
升/降压转换器 (Buck-boost) 当输入电压是变动的,有时比输出电压高.有时却比较低时(例如放电中的电池),升/降压转换器 (Buck-boost) 是最佳的电源解决方案. 升/降压转换器 ( ...
- Get buck-boost performance from a boost regulator
The SEPIC (single-ended, primary-inductance-converter) topology is generally a good choice for volta ...
- Java程序生成linechart report的方法
iReport一般是一个设计阶段的工具.用来设计出报表的排版和内容.报表的动态生成须要程序来实现(毕竟报表的数据是动态的,数量是非常多的,不可能用iReport Preview的方式一个个手工去生成) ...
- 使用Redisson实现分布式锁
原文:https://www.jianshu.com/p/cde0700f0128 1. 可重入锁(Reentrant Lock) Redisson的分布式可重入锁RLock Java对象实现了jav ...