高性能服务器(windows IOCP)

转载

http://blog.csdn.net/guestcode

/********************************************************************************
* *
* GSocket:完成端口通讯模块(IOCP Socket) *
* ——GTcpServer *
* *
* Copyright © 2009 代码客(卢益贵) 版权所有 *
* 未经许可,不得用于任何项目开发 *
* QQ:48092788 E-Mail:gcode@qq.com 源码博客:http://blog.csdn.net/guestcode *
* *
* GSN:34674B4D-1F63-11D3-B64C-11C04F79498E *
********************************************************************************/

#include "stdafx.h"
#include <winsock2.h>
#include <mswsock.h>

#include "GLog.h"
#include "GMemory.h"
#include "GWorkerThread.h"
#include "GPerIoData.h"
#include "GPerHandleData.h"
#include "GSocketInside.h"
#include "GThread.h"
#include "GSocket.h"

#if(_GSOCKET_FUNC_TCP_SERVER)

#define GTcpSvr_AcceptEx(pListener, pClient, pIoData) (pfnGSockAcceptEx(pListener->Socket, pClient->Socket, pIoData->cData, dwGSockAcceptBytes, sizeof(SOCKADDR_IN) + 16, sizeof(SOCKADDR_IN) + 16, NULL, LPWSAOVERLAPPED(pIoData)))
#define GTcpSvr_GetAcceptExSockAddrs(pListener, Buf, Bytes, Addr, Len) (pfnGSockGetAcceptExSockAddrs(Buf, Bytes, sizeof(SOCKADDR_IN) + 16, sizeof(SOCKADDR_IN) + 16, (PSOCKADDR *)&Addr, (int*)&Len, (PSOCKADDR *)&Addr, (int*)&Len))
#define GTcpSvr_DisconnectEx(pClient) (pfnGSockDisconnectEx(pClient->Socket, NULL, TF_REUSE_SOCKET, 0))

/*********************************************************************************
变量定义和初始化
*********************************************************************************/
#if(_USE_INTERLOCKED_IN_LIST)
BOOL bGTcpSvrPendingAcceptLock = FALSE;
#else
CRITICAL_SECTION GTcpSvrPendingAcceptCS;
#endif
PGHND_DATA pGTcpSvrPendingAcceptHead = NULL;
DWORD dwGTcpSvrPendingAcceptCount = 0;

#if(_USE_INTERLOCKED_IN_LIST)
BOOL bGTcpSvrClientLock = FALSE;
#else
CRITICAL_SECTION GTcpSvrClientCS;
#endif
PGHND_DATA pGTcpSvrClientHead = NULL;
DWORD dwGTcpSvrClientCount = NULL;

CRITICAL_SECTION GTcpSvrListenerCS;
DWORD dwGTcpSvrListenerCount = 0;
PGHND_DATA pGTcpSvrListeners[WSA_MAXIMUM_WAIT_EVENTS];
HANDLE hGTcpSvrListenerEvents[WSA_MAXIMUM_WAIT_EVENTS];
PGHND_DATA* pGTcpSvrOvertimeClient = NULL;
DWORD pGTcpSvrOvertimeCount = 0;
GTHREAD GTcpSvrServiceThreadData;

BOOL bGTcpSvrIsActive = FALSE;

/*********************************************************************************
内核锁
*********************************************************************************/
#if(_USE_INTERLOCKED_IN_LIST)
void GTcpSvr_LockClientList(void)
{
for(;;)
{
if(FALSE == GSock_InterlockedSet(bGTcpSvrClientLock, TRUE, FALSE))
return;
}
}

void GTcpSvr_UnlockClientList(void)
{
GSock_InterlockedSet(bGTcpSvrClientLock, FALSE, TRUE);
}

void GTcpSvr_LockPendingAcceptList(void)
{
for(;;)
{
if(FALSE == GSock_InterlockedSet(bGTcpSvrPendingAcceptLock, TRUE, FALSE))
return;
}
}

void GTcpSvr_UnlockPendingAcceptList(void)
{
GSock_InterlockedSet(bGTcpSvrPendingAcceptLock, FALSE, TRUE);
}
#endif

/*********************************************************************************
变量设置
*********************************************************************************/
DWORD GTcpSvr_GetClientCount(void)
{
return(dwGTcpSvrClientCount);
}

DWORD GTcpSvr_GetListenerCount(void)
{
return(dwGTcpSvrListenerCount);
}

DWORD GTcpSvr_GetPendingAcceptCount(void)
{
return(dwGTcpSvrPendingAcceptCount);
}

/*********************************************************************************
Listener参数获取
*********************************************************************************/
DWORD GTcpSvr_GetListenerConnectCount(DWORD dwListenerId)
{
return((DWORD)PGHND_DATA(dwListenerId)->pData);
}

void GTcpSvr_TraversalListener(DWORD dwParam, PFN_ON_GSOCK_TRAVERSAL pfnOnProc)
{
if(!bGTcpSvrIsActive)
return;

EnterCriticalSection(&GTcpSvrListenerCS);

DWORD i;

for(i = 0; i < dwGTcpSvrListenerCount; i++)
{
if(!pfnOnProc(dwParam, i, DWORD(pGTcpSvrListeners[i])))
break;
}

LeaveCriticalSection(&GTcpSvrListenerCS);
}

/*********************************************************************************
服务操作
*********************************************************************************/
void GTcpSvr_InsertClientList(PGHND_DATA pClient)
{
#if(_USE_INTERLOCKED_IN_LIST)
GTcpSvr_LockClientList();
#else
EnterCriticalSection(&GTcpSvrClientCS);
#endif

pClient->pPrior = NULL;
pClient->pNext = pGTcpSvrClientHead;
if(pGTcpSvrClientHead)
pGTcpSvrClientHead->pPrior = pClient;
pGTcpSvrClientHead = pClient;
dwGTcpSvrClientCount++;
#if(_USE_INTERLOCKED_IN_LIST)
GTcpSvr_UnlockClientList();
#else
LeaveCriticalSection(&GTcpSvrClientCS);
#endif
}

void GTcpSvr_DeleteClientList(PGHND_DATA pClient)
{
#if(_USE_INTERLOCKED_IN_LIST)
GTcpSvr_LockClientList();
#else
EnterCriticalSection(&GTcpSvrClientCS);
#endif

if(pClient == pGTcpSvrClientHead)
{
pGTcpSvrClientHead = pGTcpSvrClientHead->pNext;
if(pGTcpSvrClientHead)
pGTcpSvrClientHead->pPrior = NULL;
}else
{
pClient->pPrior->pNext = pClient->pNext;
if(pClient->pNext)
pClient->pNext->pPrior = pClient->pPrior;
}
dwGTcpSvrClientCount--;

#if(_USE_INTERLOCKED_IN_LIST)
GTcpSvr_UnlockClientList();
#else
LeaveCriticalSection(&GTcpSvrClientCS);
#endif
}

void GTcpSvr_InsertPendingAcceptList(PGHND_DATA pClient)
{
#if(_USE_INTERLOCKED_IN_LIST)
GTcpSvr_LockPendingAcceptList();
#else
EnterCriticalSection(&GTcpSvrPendingAcceptCS);
#endif

pClient->pNext = pGTcpSvrPendingAcceptHead;
if(pGTcpSvrPendingAcceptHead)
pGTcpSvrPendingAcceptHead->pPrior = pClient;
pClient->pPrior = NULL;
pGTcpSvrPendingAcceptHead = pClient;
dwGTcpSvrPendingAcceptCount++;

#if(_USE_INTERLOCKED_IN_LIST)
GTcpSvr_UnlockPendingAcceptList();
#else
LeaveCriticalSection(&GTcpSvrPendingAcceptCS);
#endif
}
void GTcpSvr_DeletePendingAcceptList(PGHND_DATA pClient)
{
#if(_USE_INTERLOCKED_IN_LIST)
GTcpSvr_LockPendingAcceptList();
#else
EnterCriticalSection(&GTcpSvrPendingAcceptCS);
#endif

if(pClient == pGTcpSvrPendingAcceptHead)
{
pGTcpSvrPendingAcceptHead = pGTcpSvrPendingAcceptHead->pNext;
if(pGTcpSvrPendingAcceptHead)
pGTcpSvrPendingAcceptHead->pPrior = NULL;
}else
{
pClient->pPrior->pNext = pClient->pNext;
if(pClient->pNext)
pClient->pNext->pPrior = pClient->pPrior;
}
dwGTcpSvrPendingAcceptCount--;

#if(_USE_INTERLOCKED_IN_LIST)
GTcpSvr_UnlockPendingAcceptList();
#else
LeaveCriticalSection(&GTcpSvrPendingAcceptCS);
#endif
}

void GTcpSvr_TraversalClient(DWORD dwParam, DWORD dwFromIndex, DWORD dwCount, PFN_ON_GSOCK_TRAVERSAL pfnOnProc)
{
if(!bGTcpSvrIsActive)
return;

#if(_USE_INTERLOCKED_IN_LIST)
GTcpSvr_LockClientList();
#else
EnterCriticalSection(&GTcpSvrClientCS);
#endif

PGHND_DATA pClient;
DWORD dwIndex;

dwIndex = 0;
dwCount = dwFromIndex + dwCount;
pClient = pGTcpSvrClientHead;
while(pClient)
{
if(dwIndex >= dwFromIndex)
{
if((dwIndex >= dwCount) || (!pfnOnProc(dwParam, dwIndex, (DWORD)pClient)))
break;
}
dwIndex++;
pClient = pClient->pNext;
}

#if(_USE_INTERLOCKED_IN_LIST)
GTcpSvr_UnlockClientList();
#else
LeaveCriticalSection(&GTcpSvrClientCS);
#endif
}
免费领取CSDN积分大礼包
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理

GuestCode
GuestCode
等级: #2 得分:0
回复于: 2009-09-21 12:00:25
void GTcpSvr_OnReadWriteError(PGHND_DATA pClient, PGIO_DATA pIoData)
{
if(GIO_WRITE_COMPLETED == pIoData->OperType)
pfnOnGSockSendErrorSvr((DWORD)pClient, pIoData->cData, pIoData->WSABuf.len);
GIoDat_Free(pIoData);

if(GHND_STATE_CONNECTED != GSock_InterlockedSet(pClient->hsState, GHND_STATE_DISCONNECT, GHND_STATE_CONNECTED))
return;

GTcpSvr_DeleteClientList(pClient);
GSock_InterlockedDec(PGHND_DATA(pClient->pOwner)->pData);
pfnOnGSockDisconnectSvr((DWORD)pClient);

if(GIO_CONNECTION_OVERFLOW == pIoData->OperType)
{
pfnOnGSockConnectionOverflow((DWORD)pClient);
GSock_UninitTcpHndData(pClient);
#if(_REUSED_SOCKET)
GSock_InitTcpHndData(pClient);
#endif
GHndDat_Free(pClient);
}else
if(GIO_IDLE_OVERTIME == pIoData->OperType)
{
pfnOnGSockIdleOvertime((DWORD)pClient);
GSock_UninitTcpHndData(pClient);
#if(_REUSED_SOCKET)
GSock_InitTcpHndData(pClient);
#endif
GHndDat_Free(pClient);
}else
if(GIO_CLOSE == pIoData->OperType)
{
GSock_UninitTcpHndData(pClient);
#if(_REUSED_SOCKET)
GSock_InitTcpHndData(pClient);
#endif
GHndDat_Free(pClient);
}else
{
#if(_REUSED_SOCKET)
GTcpSvr_DisconnectEx(pClient);
#else
GSock_UninitTcpHndData(pClient);
#endif
GHndDat_Free(pClient);
}

}

void GTcpSvr_OnReadWrite(DWORD dwBytes, PGHND_DATA pClient, PGIO_DATA pIoData)
{
if(!dwBytes)
{
if(bGSockIsZeroByteRecv && (GHND_STATE_CONNECTED == pClient->hsState) && (GIO_READ_COMPLETED == pIoData->OperType))
{
GIoDat_ResetIoDataOnRead(pIoData);
pIoData->OperType = GIO_ZERO_READ_COMPLETED;
pIoData->WSABuf.len = dwGBufSize;
dwBytes = 0;
DWORD dwFlag = 0;
if((SOCKET_ERROR != WSARecv(pClient->Socket, &(pIoData->WSABuf), 1, &dwBytes, &dwFlag, LPWSAOVERLAPPED(pIoData), NULL)) ||
(ERROR_IO_PENDING == WSAGetLastError()))
{
return;
}
}
GTcpSvr_OnReadWriteError(pClient, pIoData);
return;
}

if(GIO_WRITE_COMPLETED == pIoData->OperType)
{
pfnOnGSockSendedSvr((DWORD)pClient, pIoData->cData, dwBytes);
GIoDat_Free(pIoData);
}else
{
pClient->dwTickCountAcitve = GetTickCount();
#if(_USE_GPROTOCOL)
if(GCommProt_ProcessReceive(pClient, pIoData->cData, dwBytes, pfnOnGSockReceiveSvr))
{
pIoData = GIoDat_Alloc();
if(!pIoData)
{
GLog_Write("GTcpSvr_OnReadWrite:IoData分配失败,无法再投递接收");
return;
}
}
#else
pfnOnGSockReceiveSvr((DWORD)pClient, pIoData->cData, dwBytes);
#endif

GIoDat_ResetIoDataOnRead(pIoData);
pIoData->OperType = GIO_READ_COMPLETED;
pIoData->WSABuf.len = dwGSockRecvBytes;
dwBytes = 0;
DWORD dwFlag = 0;
if((SOCKET_ERROR == WSARecv(pClient->Socket, &(pIoData->WSABuf), 1, &dwBytes, &dwFlag, LPWSAOVERLAPPED(pIoData), NULL)) &&
(ERROR_IO_PENDING != WSAGetLastError()))
{
GTcpSvr_OnReadWriteError(pClient, pIoData);
}
}
}

BOOL GTcpSvr_PostAccept(PGHND_DATA pListener, DWORD dwCount)
{
int nCount;
PGHND_DATA pClient;
PGIO_DATA pIoData;

nCount = 0;

while(dwCount && (dwGTcpSvrClientCount + dwGTcpSvrPendingAcceptCount < dwGSockMaxNumberConnection))
{
pClient = GHndDat_Alloc();
if(!pClient)
{
GLog_Write("GTcpSvr_PostAccept:分配HndData失败,无法投递接受");
return(nCount);
}
#if(!_REUSED_SOCKET)
GSock_InitTcpHndData(pClient);
#endif
pIoData = GIoDat_Alloc();
if(!pIoData)
{
#if(!_REUSED_SOCKET)
GSock_UninitTcpHndData(pClient);
#endif
GHndDat_Free(pClient);
GLog_Write("GTcpSvr_PostAccept:分配IoData失败,无法投递接受");
return(nCount);
}

pClient->pfnOnIocpOper = &GTcpSvr_OnReadWrite;
pClient->pfnOnIocpError = &GTcpSvr_OnReadWriteError;
pClient->htType = GHND_TYPE_TCP_SVR_CLIENT;
pClient->hsState = GHND_STATE_ACCEPTING;
pClient->pOwner = pListener;
pClient->pData = NULL;

pIoData->OperType = GIO_CONNECTED;
pIoData->pOwner = pClient;
pIoData->WSABuf.len = dwGSockRecvBytes;

GTcpSvr_InsertPendingAcceptList(pClient);
if((!GTcpSvr_AcceptEx(pListener, pClient, pIoData)) && (ERROR_IO_PENDING != WSAGetLastError()))
{
GTcpSvr_DeletePendingAcceptList(pClient);
GIoDat_Free(pIoData);
#if(!_REUSED_SOCKET)
GSock_UninitTcpHndData(pClient);
#endif
GHndDat_Free(pClient);
GLog_Write("GTcpSvr_PostAccept:执行pfnGTcpSvrAcceptEx失败,无法投递接受");
return(nCount);
}
dwCount--;
nCount++;
}//for(i = 0; i < dwCount; i++)

return(TRUE);
}

void GTcpSvr_OnAcceptError(PGHND_DATA pListener, PGIO_DATA pIoData)
{
PGHND_DATA pClient = PGHND_DATA(pIoData->pOwner);
GIoDat_Free(pIoData);

if(GHND_STATE_ACCEPTING != GSock_InterlockedSet(pClient->hsState, GHND_STATE_DISCONNECT, GHND_STATE_ACCEPTING))
return;

GTcpSvr_DeletePendingAcceptList(pClient);
if(GIO_CLOSE == pIoData->OperType)
{
GSock_UninitTcpHndData(pClient);
GHndDat_Free(pClient);
}else
{
#if(_REUSED_SOCKET)
GTcpSvr_DisconnectEx(pClient);
#else
GSock_UninitTcpHndData(pClient);
#endif
GHndDat_Free(pClient);
}
}

void GTcpSvr_OnAccept(DWORD dwBytes, PGHND_DATA pListener, PGIO_DATA pIoData)
{
if((!dwBytes) && (dwGSockAcceptBytes))
{
GTcpSvr_OnAcceptError(pListener, pIoData);
return;
}

PGHND_DATA pClient;
PSOCKADDR_IN pAddr;
int nLen;

pClient = PGHND_DATA(pIoData->pOwner);
GTcpSvr_DeletePendingAcceptList(pClient);
setsockopt(pClient->Socket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char *)&(pListener->Socket), sizeof(pListener->Socket));
BOOL bDontLinger = FALSE;
setsockopt(pClient->Socket, SOL_SOCKET, SO_DONTLINGER, (const char *) &bDontLinger, sizeof(BOOL));

GTcpSvr_GetAcceptExSockAddrs(pListener, pIoData->cData, dwGSockAcceptBytes, pAddr, nLen);
pClient->dwAddr = pAddr->sin_addr.S_un.S_addr;
pClient->dwPort = htons(pAddr->sin_port);
pClient->hsState = GHND_STATE_CONNECTED;
pClient->dwTickCountAcitve = GetTickCount();

GTcpSvr_InsertClientList(pClient);
GSock_InterlockedAdd(PGHND_DATA(pClient->pOwner)->pData);
#if(_USE_GPROTOCOL)
if(GCommProt_ProcessReceive(pClient, pIoData->cData, dwBytes, pfnOnGSockConnectTcpSvr))
{
pIoData = GIoDat_Alloc();
if(!pIoData)
{
GLog_Write("GTcpSvr_OnAccept:IoData分配失败,连接后无法再投递接收");
return;
}
}
#else
pfnOnGSockConnectTcpSvr((DWORD)pClient, pIoData->cData, dwBytes);
#endif

ZeroMemory(pIoData, sizeof(WSAOVERLAPPED));
DWORD dwCount = dwGSockNumberPostRecv;
for(;;)
{
GIoDat_ResetIoDataOnRead(pIoData);
pIoData->OperType = GIO_READ_COMPLETED;
pIoData->WSABuf.len = dwGSockRecvBytes;
dwBytes = 0;
DWORD dwFlag = 0;
if((SOCKET_ERROR == WSARecv(pClient->Socket, &(pIoData->WSABuf), 1, &dwBytes, &dwFlag, LPWSAOVERLAPPED(pIoData), NULL)) &&
(ERROR_IO_PENDING != WSAGetLastError()))
{
GTcpSvr_OnReadWriteError(pClient, pIoData);
break;
}
dwCount--;
if(!dwCount)
break;
pIoData = GIoDat_Alloc();
if(!pIoData)
{
GLog_Write("GTcpSvr_OnAccept:申请IoData失败,连接后无法投递接收");
break;
}
pIoData->pOwner = pClient;
}
if(dwGTcpSvrClientCount >= dwGSockMaxNumberConnection)
{
pfnOnGSockConnectionOverflow((DWORD)pClient);
void GTcpSvr_DoCloseClient(PGHND_DATA pClient, PGHND_DATA pIoDataOwner, GIO_OPER_TYPE OperType);
GTcpSvr_DoCloseClient(pClient, pClient, GIO_CLOSE);
GLog_Write("GTcpSvr_OnAccept:连接超过最大值");
}
}

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值