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:连接超过最大值");
}
}

解决方案 »

  1.   

    由于台式机太老,用尽CPU还是不能用完带宽(其中大部分被“system”进程使用),因此改做服务器,由笔记本做客户端,发起密集数据,以堵塞的情况来满负荷使用网络,收发接近:10MB。 
    ------------------------------------
    实际上在IOCP上投递IO操作的时候,是由内核线程来为你代劳的,内核线程所占用的CPU,归到“system”进程里,但此例中,实际应算在你程序的头上。准确来说,LZ的程序占用了整个CPU。
      

  2.   


    机子太老,要吃完100M带宽不占CPU,占什么?你可以使用你的机子测试看看,吃完100M带宽会耗多少CPU?
      

  3.   

    谢谢分享,最近正在研究 SOCKET这边的东西
      

  4.   

    最近正在研究 SOCKET这边的东西