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调用,不多说明!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值