前面分析了对socket基本操作的封装,并按照数据的传送方式写了两个类,本篇将写一个代理类提供给库的使用者使用的类。
[cpp] view
plaincopyprint?
/***************************************************************************************
****************************************************************************************
* 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.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_*/
上面是头文件有比较详细的注释,通过函数名也可以看出函数的意义。
[cpp] view
plaincopyprint?
/***************************************************************************************
****************************************************************************************
* 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;
}
}
/***************************************************************************************
****************************************************************************************
*
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三个函数中有所处理。