#include "stdafx.h"
#include "Net.h"
using namespace netcomm;
/*********************************************************************************************************************
2009-3-12 增加了OnReceiveBegin, OnReceiveEnd接口
修改了接收数据的逻辑: 按块接收数据, 当发送方发来一块数据时, 首先OnReceiveBegin会被调用以通知该块数据的大小,
接着OnReceive会被调用以接收实际的数据, 由于本程序接收缓冲区是固定有限的,为4096字节,因此OnReceive可能会被调
用多次. 这个次数为大于等于值(发送方数据块大小除以4096)的最小整数.当全部块数据接收完成时,会调用OnReceiveEnd
来通知程序
2009-3-18 因考虑到异步接受连接,可能还有未决的套接字, 当接受出错错误时,应该关闭套接字.因此增加了InsertSocketObjToPendingAcceptList,
RemoveSocketObjFromPendingAcceptList,FreeAllPendingAcceptSocketObj三个函数来处理这一问题
*********************************************************************************************************************/
CNet::CNet():
m_bStart(FALSE),
m_bStop(FALSE)
{
}
CNet::~CNet()
{
}
//////////////////////////////////////////////////////////////////////////
/**
* @brief 启动服务
* 绑定端口, 开始监听接受连接
@param wPort 监听端口
@return TRUE表示启动服务成功,FALSE表示启动失败
*/
//////////////////////////////////////////////////////////////////////////
BOOL CNet::Start(WORD wPort)
{
if (m_bStart)
{
return FALSE;
}
m_bStop = FALSE;
// 创建监听套节字,绑定到本地端口,进入监听模式
SOCKET sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
SOCKADDR_IN si;
si.sin_family = AF_INET;
si.sin_port = ::ntohs(wPort);
si.sin_addr.S_un.S_addr = INADDR_ANY;
if(::bind(sListen, (sockaddr*)&si, sizeof(si)) == SOCKET_ERROR)
{
TRACE("bind Failed %d \n", WSAGetLastError());
closesocket(sListen);
m_bStart = FALSE;
return FALSE;
}
::listen(sListen, 100);
PSOCKET_OBJ pSocketObj = AllocSocketObj(sListen);
if (NULL == pSocketObj)
{
closesocket(sListen);
return FALSE;
}
memcpy(&pSocketObj->addr, &si, sizeof(si));
// 加载扩展函数AcceptEx
GUID GuidAcceptEx = WSAID_ACCEPTEX;
DWORD dwchars;
int rc = WSAIoctl(pSocketObj->s,
SIO_GET_EXTENSION_FUNCTION_POINTER,
&GuidAcceptEx,
sizeof(GuidAcceptEx),
&pSocketObj->lpfnAcceptEx,
sizeof(pSocketObj->lpfnAcceptEx),
&dwchars,
NULL,
NULL);
if (SOCKET_ERROR == rc)
{
TRACE("WSAIoctl GET_EXTENSION_FUNCTION_POINTER Failed %d \n", WSAGetLastError());
FreeSocketObj(pSocketObj);
return FALSE;
}
PBUFFER_OBJ pBufferObj = AllocBufferObj(pSocketObj);
if (NULL == pBufferObj)
{
FreeSocketObj(pSocketObj);
return FALSE;
}
if (!AssignToIoThread(pBufferObj))
{
FreeSocketObj(pSocketObj);
return FALSE;
}
if (!PostAccept(pBufferObj))
{
FreeSocketObj(pSocketObj);
RemoveBufferObjFromThread(pBufferObj);
return FALSE;
}
InsertSocketObjToPendingAcceptList(pBufferObj->s);
InsertSocketObjToListenList(pSocketObj);
m_bStart = TRUE;
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
/**
@brief 停止服务
* 关闭所有连接,退出工作线程,释放所有内存
*/
//////////////////////////////////////////////////////////////////////////
void CNet::Stop()
{
m_bStart = FALSE;
m_bStop = TRUE;
CloseAllListenSocketObj();
CloseAllConnection();
SignalAllThreadObj();
ExitAllThreadObj();
FreeAllListenSocketObj();
FreeAllPendingAcceptSocketObj();
FreeAllClientSocketObj();
FreeAllServerSocketObj();
FreeAllThreadObj();
}
//////////////////////////////////////////////////////////////////////////
/**
@brief 关闭所有连接
* 这些连接包括作为服务器与客户端的连接,作为客户端与服务器的连接
*/
//////////////////////////////////////////////////////////////////////////
inline void CNet::CloseAllConnection()
{
CloseAllClientSocketObj();
CloseAllServerSocketObj();
}
//////////////////////////////////////////////////////////////////////////
/**
使所有线程受信
*/
//////////////////////////////////////////////////////////////////////////
inline void CNet::SignalAllThreadObj()
{
InnerLock lock(m_cs_ThreadObjList);
for (ThreadObjIter iter = m_ThreadObjList.begin(); iter != m_ThreadObjList.end(); ++iter)
{
PTHREAD_OBJ pThreadObj = *iter;
SetEvent(pThreadObj->hExitEvent);
}
TRACE("SignalAllThreadObj, Thread = %d \n", m_ThreadObjList.size());
}
//////////////////////////////////////////////////////////////////////////
/**
退出所有线程
*/
//////////////////////////////////////////////////////////////////////////
inline void CNet::ExitAllThreadObj()
{
for (ThreadObjIter iter = m_ThreadObjList.begin(); iter != m_ThreadObjList.end(); ++iter)
{
ExitThreadObj(*iter);
}
}
//////////////////////////////////////////////////////////////////////////
/**
释放所有线程对象
*/
//////////////////////////////////////////////////////////////////////////
inline void CNet::FreeAllThreadObj()
{
TRACE("FreeAllThreadObj, Thread = %d \n", m_ThreadObjList.size());
for (ThreadObjIter iter = m_ThreadObjList.begin(); iter != m_ThreadObjList.end(); )
{
PTHREAD_OBJ pThreadObj = *iter;
iter = m_ThreadObjList.erase(iter);
FreeThreadObj(pThreadObj);
}
}
//////////////////////////////////////////////////////////////////////////
/**
关闭所有监听套接字
*/
//////////////////////////////////////////////////////////////////////////
inline void CNet::CloseAllListenSocketObj()
{
InnerLock lock(m_cs_ListenList);
for (SocketObjIter iter = m_ListenList.begin(); iter != m_ListenList.end(); ++iter)
{
PSOCKET_OBJ pSocketObj = *iter;
if (pSocketObj->s != INVALID_SOCKET)
{
closesocket(pSocketObj->s);
pSocketObj->s = INVALID_SOCKET;
}
}
}
//////////////////////////////////////////////////////////////////////////
/**
释放所有监听套接字对象
*/
//////////////////////////////////////////////////////////////////////////
inline void CNet::FreeAllListenSocketObj()
{
InnerLock lock(m_cs_ListenList);
for (SocketObjIter iter = m_ListenList.begin(); iter != m_ListenList.end(); )
{
PSOCKET_OBJ pSocketObj = *iter;
iter = m_ListenList.erase(iter);
FreeSocketObj(pSocketObj);
}
}
//////////////////////////////////////////////////////////////////////////
/**
向未决接受列表插入套接字
*/
//////////////////////////////////////////////////////////////////////////
inline void CNet::InsertSocketObjToPendingAcceptList(const SOCKET s)
{
ASSERT(s != INVALID_SOCKET);
InnerLock lock(m_cs_PendingAcceptList);
m_PendingAcceptList.push_back(s);
}
//////////////////////////////////////////////////////////////////////////
/**
从未决接受列表移除套接字
*/
//////////////////////////////////////////////////////////////////////////
inline void CNet::RemoveSocketObjFromPendingAcceptList(const SOCKET s)
{
ASSERT(s != INVALID_SOCKET);
InnerLock lock(m_cs_PendingAcceptList);
m_PendingAcceptList.remove(s);
}
//////////////////////////////////////////////////////////////////////////
/**
关闭所有未决接受套接字
*/
//////////////////////////////////////////////////////////////////////////
inline void CNet::FreeAllPendingAcceptSocketObj()
{
for (list<SOCKET>::iterator iter = m_PendingAcceptList.begin(); iter != m_PendingAcceptList.end(); )
{
closesocket((*iter));
iter = m_PendingAcceptList.erase(iter);
}
}
//////////////////////////////////////////////////////////////////////////
/**
向监听列表插入套接字对象
*/
//////////////////////////////////////////////////////////////////////////
inline void CNet::InsertSocketObjToListenList(const PSOCKET_OBJ pSocketObj)
{
ASSERT(pSocketObj);
InnerLock lock(m_cs_ListenList);
m_ListenList.push_back(pSocketObj);
}
//////////////////////////////////////////////////////////////////////////
/*