您的位置:首页 > 运维架构 > Linux

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

2014-04-18 11:52 465 查看
把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调用,不多说明!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: