Files
wnmj/Servers/服务器组件/内核引擎/TCPNetworkEngine.cpp

1511 lines
38 KiB
C++
Raw Normal View History

2026-02-13 14:34:15 +08:00
#include "StdAfx.h"
#include "TraceService.h" //
#include "TCPNetworkEngine.h"
//////////////////////////////////////////////////////////////////////////
//<2F><EFBFBD><EAB6A8>
#define TIME_BREAK_READY 9000L //<2F>ж<EFBFBD>ʱ<EFBFBD><CAB1>
#define TIME_BREAK_CONNECT 4000L //<2F>ж<EFBFBD>ʱ<EFBFBD><CAB1>
#define TIME_DETECT_SOCKET 10000L //<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
//////////////////////////////////////////////////////////////////////////
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define QUEUE_SEND_REQUEST 1 //<2F><><EFBFBD>ͱ<EFBFBD>ʶ
#define QUEUE_SAFE_CLOSE 2 //<2F><>ȫ<EFBFBD>ر<EFBFBD>
#define QUEUE_ALLOW_BATCH 3 //<2F><><EFBFBD><EFBFBD>Ⱥ<EFBFBD><C8BA>
#define QUEUE_DETECT_SOCKET 4 //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
struct tagSendDataRequest
{
WORD wMainCmdID; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
WORD wSubCmdID; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
DWORD dwSocketID; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
WORD wDataSize; //<2F><><EFBFBD>ݴ<EFBFBD>С
BYTE cbSendBuf[SOCKET_TCP_BUFFER]; //<2F><><EFBFBD>ͻ<EFBFBD><CDBB><EFBFBD>
};
//<2F><><EFBFBD><EFBFBD>Ⱥ<EFBFBD><C8BA>
struct tagAllowBatchSend
{
DWORD dwSocketID; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
BYTE cbAllow; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
};
//<2F><>ȫ<EFBFBD>ر<EFBFBD>
struct tagSafeCloseSocket
{
DWORD dwSocketID; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
};
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E1B9B9>Ϣ
struct TCP_KN_DetectSocket
{
DWORD dwSendTickCount; //<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
DWORD dwRecvTickCount; //<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
};
//////////////////////////////////////////////////////////////////////////
//<2F><><EFBFBD><EFBFBD><ECBAAF>
COverLapped::COverLapped(enOperationType OperationType) : m_OperationType(OperationType)
{
memset(&m_WSABuffer, 0, sizeof(m_WSABuffer));
memset(&m_OverLapped, 0, sizeof(m_OverLapped));
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
COverLapped::~COverLapped()
{
}
//////////////////////////////////////////////////////////////////////////
//<2F><><EFBFBD><EFBFBD><ECBAAF>
COverLappedSend::COverLappedSend() : COverLapped(OperationType_Send)
{
m_WSABuffer.len = 0;
m_WSABuffer.buf = (char *)m_cbBuffer;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
COverLappedSend::~COverLappedSend()
{
}
//////////////////////////////////////////////////////////////////////////
//<2F><><EFBFBD><EFBFBD><ECBAAF>
CServerSocketItem::CServerSocketItem(WORD wIndex, IServerSocketItemSink * pIServerSocketItemSink)
: m_wIndex(wIndex), m_pIServerSocketItemSink(pIServerSocketItemSink)
{
m_wRountID = 1;
m_wRecvSize = 0;
m_cbSendRound = 0;
m_cbRecvRound = 0;
m_bNotify = true;
m_bRecvIng = false;
m_bCloseIng = false;
m_bAllowBatch = true;
m_dwSendXorKey = 0;
m_dwRecvXorKey = 0;
m_dwClientAddr = 0;
m_dwConnectTime = 0;
m_dwSendTickCount = 0;
m_dwRecvTickCount = 0;
m_dwSendPacketCount = 0;
m_dwRecvPacketCount = 0;
m_hSocket = INVALID_SOCKET;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CServerSocketItem::~CServerSocketItem(void)
{
//ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD> IO
INT_PTR iCount = m_OverLappedSendFree.GetCount();
for (INT_PTR i = 0; i < iCount; i++) delete m_OverLappedSendFree[i];
m_OverLappedSendFree.RemoveAll();
//ɾ<><C9BE><EFBFBD><EFBFBD>ص<EFBFBD> IO
iCount = m_OverLappedSendActive.GetCount();
for (INT_PTR i = 0; i < iCount; i++) delete m_OverLappedSendActive[i];
m_OverLappedSendActive.RemoveAll();
return;
}
//<2F><><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3>
WORD CServerSocketItem::SeedRandMap(WORD wSeed)
{
DWORD dwHold = wSeed;
return (WORD)((dwHold = dwHold * 241103L + 2533101L) >> 16);
}
//ӳ<><EFBFBD><E4B7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
BYTE CServerSocketItem::MapSendByte(BYTE const cbData)
{
//BYTE cbMap = g_SendByteMap[(BYTE)(cbData+m_cbSendRound)];
//m_cbSendRound += 3;
BYTE cbMap = g_SendByteMap[(BYTE)(cbData)];
return cbMap;
}
//ӳ<><D3B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
BYTE CServerSocketItem::MapRecvByte(BYTE const cbData)
{
//BYTE cbMap = g_RecvByteMap[cbData] - m_cbRecvRound;
//m_cbRecvRound += 3;
BYTE cbMap = g_RecvByteMap[cbData];
return cbMap;
}
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD>ͽṹ
COverLappedSend * CServerSocketItem::GetSendOverLapped()
{
//Ѱ<>ҿ<EFBFBD><D2BF>нṹ
COverLappedSend * pOverLappedSend = NULL;
INT_PTR nFreeCount = m_OverLappedSendFree.GetCount();
if (nFreeCount > 0)
{
pOverLappedSend = m_OverLappedSendFree[nFreeCount-1];
ASSERT(pOverLappedSend != NULL);
m_OverLappedSendFree.RemoveAt(nFreeCount - 1);
m_OverLappedSendActive.Add(pOverLappedSend);
return pOverLappedSend;
}
//<2F>½<EFBFBD><C2BD><EFBFBD><EFBFBD>ͽṹ
try
{
pOverLappedSend = new COverLappedSend;
ASSERT(pOverLappedSend != NULL);
m_OverLappedSendActive.Add(pOverLappedSend);
return pOverLappedSend;
}
catch (...) { }
return NULL;
}
//<2F>󶨶<EFBFBD><F3B6A8B6><EFBFBD>
DWORD CServerSocketItem::Attach(SOCKET hSocket, DWORD dwClientAddr)
{
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ASSERT(dwClientAddr != 0);
ASSERT(m_bRecvIng == false);
ASSERT(IsValidSocket() == false);
ASSERT(hSocket != INVALID_SOCKET);
//<2F><><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD>
m_bNotify = false;
m_bRecvIng = false;
m_bCloseIng = false;
m_hSocket = hSocket;
m_dwClientAddr = dwClientAddr;
m_dwRecvTickCount = GetTickCount();
m_dwConnectTime = (DWORD)time(NULL);
//<2F><><EFBFBD><EFBFBD>֪ͨ
m_pIServerSocketItemSink->OnSocketAcceptEvent(this);
return GetSocketID();
}
//<2F><><EFBFBD>ͺ<EFBFBD><CDBA><EFBFBD>
bool CServerSocketItem::SendData(WORD wMainCmdID, WORD wSubCmdID, WORD wRountID)
{
//Ч<><D0A7>״̬
if (m_bCloseIng == true) return false;
if (m_wRountID != wRountID) return false;
if (m_dwRecvPacketCount == 0) return false;
if (IsValidSocket() == false) return false;
//Ѱ<>ҷ<EFBFBD><D2B7>ͽṹ
COverLappedSend * pOverLappedSend = GetSendOverLapped();
ASSERT(pOverLappedSend != NULL);
if (pOverLappedSend == NULL) return false;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TCP_Head * pHead = (TCP_Head *)pOverLappedSend->m_cbBuffer;
pHead->CommandInfo.wMainCmdID = wMainCmdID;
pHead->CommandInfo.wSubCmdID = wSubCmdID;
WORD wSendSize = EncryptBuffer(pOverLappedSend->m_cbBuffer, sizeof(TCP_Head), sizeof(pOverLappedSend->m_cbBuffer));
pOverLappedSend->m_WSABuffer.len = wSendSize;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (m_OverLappedSendActive.GetCount() == 1)
{
DWORD dwThancferred = 0;
int iRetCode = WSASend(m_hSocket, &pOverLappedSend->m_WSABuffer, 1, &dwThancferred, 0, &pOverLappedSend->m_OverLapped, NULL);
if ((iRetCode == SOCKET_ERROR) && (WSAGetLastError() != WSA_IO_PENDING))
{
OnSendCompleted(pOverLappedSend, 0L);
return false;
}
}
return true;
}
//<2F><><EFBFBD>ͺ<EFBFBD><CDBA><EFBFBD>
bool CServerSocketItem::SendData(void * pData, WORD wDataSize, WORD wMainCmdID, WORD wSubCmdID, WORD wRountID)
{
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ASSERT(wDataSize <= SOCKET_TCP_BUFFER);
//Ч<><D0A7>״̬
if (m_bCloseIng == true) return false;
if (m_wRountID != wRountID) return false;
if (m_dwRecvPacketCount == 0) return false;
if (IsValidSocket() == false) return false;
if (wDataSize > SOCKET_TCP_BUFFER) return false;
//Ѱ<>ҷ<EFBFBD><D2B7>ͽṹ
COverLappedSend * pOverLappedSend = GetSendOverLapped();
ASSERT(pOverLappedSend != NULL);
if (pOverLappedSend == NULL) return false;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TCP_Head * pHead = (TCP_Head *)pOverLappedSend->m_cbBuffer;
pHead->CommandInfo.wMainCmdID = wMainCmdID;
pHead->CommandInfo.wSubCmdID = wSubCmdID;
if (wDataSize > 0)
{
ASSERT(pData != NULL);
memcpy(pHead + 1, pData, wDataSize);
}
WORD wSendSize = EncryptBuffer(pOverLappedSend->m_cbBuffer, sizeof(TCP_Head) + wDataSize, sizeof(pOverLappedSend->m_cbBuffer));
pOverLappedSend->m_WSABuffer.len = wSendSize;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (m_OverLappedSendActive.GetCount() == 1)
{
DWORD dwThancferred = 0;
int iRetCode = WSASend(m_hSocket, &pOverLappedSend->m_WSABuffer, 1, &dwThancferred, 0, &pOverLappedSend->m_OverLapped, NULL);
if ((iRetCode == SOCKET_ERROR) && (WSAGetLastError() != WSA_IO_PENDING))
{
OnSendCompleted(pOverLappedSend, 0L);
return false;
}
}
return true;
}
//Ͷ<>ݽ<EFBFBD><DDBD><EFBFBD>
bool CServerSocketItem::RecvData()
{
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ASSERT(m_bRecvIng == false);
ASSERT(m_hSocket != INVALID_SOCKET);
//<2F>жϹر<CFB9>
if (m_bCloseIng == true)
{
if (m_OverLappedSendActive.GetCount() == 0) CloseSocket(m_wRountID);
return false;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m_bRecvIng = true;
DWORD dwThancferred = 0, dwFlags = 0;
int iRetCode = WSARecv(m_hSocket, &m_OverLappedRecv.m_WSABuffer, 1, &dwThancferred, &dwFlags, &m_OverLappedRecv.m_OverLapped, NULL);
if ((iRetCode == SOCKET_ERROR) && (WSAGetLastError() != WSA_IO_PENDING))
{
m_bRecvIng = false;
CloseSocket(m_wRountID);
return false;
}
return true;
}
//<2F>ر<EFBFBD><D8B1><EFBFBD><EFBFBD><EFBFBD>
bool CServerSocketItem::CloseSocket(WORD wRountID)
{
//״̬<D7B4>ж<EFBFBD>
if (m_wRountID != wRountID) return false;
//<2F>ر<EFBFBD><D8B1><EFBFBD><EFBFBD><EFBFBD>
if (m_hSocket != INVALID_SOCKET)
{
closesocket(m_hSocket);
m_hSocket = INVALID_SOCKET;
}
//<2F>жϹر<CFB9>
if ((m_bRecvIng == false) && (m_OverLappedSendActive.GetCount() == 0)) OnCloseCompleted();
return true;
}
//<2F><><EFBFBD>ùر<C3B9>
bool CServerSocketItem::ShutDownSocket(WORD wRountID)
{
return true;
//״̬<D7B4>ж<EFBFBD>
if (m_wRountID != wRountID) return false;
if (m_hSocket == INVALID_SOCKET) return false;
//<2F><><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD>
if (m_bCloseIng == false)
{
m_bCloseIng = true;
//if (m_OverLappedSendActive.GetCount() == 0) CloseSocket(wRountID);
}
return true;
}
//<2F><><EFBFBD><EFBFBD>Ⱥ<EFBFBD><C8BA>
bool CServerSocketItem::AllowBatchSend(WORD wRountID, bool bAllowBatch)
{
//״̬<D7B4>ж<EFBFBD>
if (m_wRountID != wRountID) return false;
if (m_hSocket == INVALID_SOCKET) return false;
//<2F><><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD>
m_bAllowBatch = bAllowBatch;
return true;
}
//<2F><><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD>
void CServerSocketItem::ResetSocketData()
{
//Ч<><D0A7>״̬
ASSERT(m_hSocket == INVALID_SOCKET);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m_wRountID++;
m_wRecvSize = 0;
m_cbSendRound = 0;
m_cbRecvRound = 0;
m_dwSendXorKey = 0;
m_dwRecvXorKey = 0;
m_dwClientAddr = 0;
m_dwConnectTime = 0;
m_dwSendTickCount = 0;
m_dwRecvTickCount = 0;
m_dwSendPacketCount = 0;
m_dwRecvPacketCount = 0;
//״̬<D7B4><CCAC><EFBFBD><EFBFBD>
m_bNotify = true;
m_bRecvIng = false;
m_bCloseIng = false;
m_bAllowBatch = true;
m_OverLappedSendFree.Append(m_OverLappedSendActive);
m_OverLappedSendActive.RemoveAll();
return;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA><EFBFBD>
bool CServerSocketItem::OnSendCompleted(COverLappedSend * pOverLappedSend, DWORD dwThancferred)
{
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ASSERT(pOverLappedSend != NULL);
ASSERT(m_OverLappedSendActive.GetCount() > 0);
ASSERT(pOverLappedSend == m_OverLappedSendActive[0]);
//<2F>ͷŷ<CDB7><C5B7>ͽṹ
m_OverLappedSendActive.RemoveAt(0);
m_OverLappedSendFree.Add(pOverLappedSend);
//<2F><><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD>
if (dwThancferred != 0) m_dwSendTickCount = GetTickCount();
//<2F>жϹر<CFB9>
if (m_hSocket == INVALID_SOCKET)
{
m_OverLappedSendFree.Append(m_OverLappedSendActive);
m_OverLappedSendActive.RemoveAll();
CloseSocket(m_wRountID);
return true;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (m_OverLappedSendActive.GetCount() > 0)
{
DWORD dwThancferred = 0;
pOverLappedSend = m_OverLappedSendActive[0];
ASSERT(pOverLappedSend != NULL);
int iRetCode = WSASend(m_hSocket, &pOverLappedSend->m_WSABuffer, 1, &dwThancferred, 0, &pOverLappedSend->m_OverLapped, NULL);
if ((iRetCode == SOCKET_ERROR) && (WSAGetLastError() != WSA_IO_PENDING))
{
m_OverLappedSendFree.Append(m_OverLappedSendActive);
m_OverLappedSendActive.RemoveAll();
CloseSocket(m_wRountID);
return false;
}
return true;
}
//<2F>жϹر<CFB9>
if (m_bCloseIng == true)
CloseSocket(m_wRountID);
return true;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA><EFBFBD>
bool CServerSocketItem::OnRecvCompleted(COverLappedRecv * pOverLappedRecv, DWORD dwThancferred)
{
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ASSERT(m_bRecvIng == true);
//<2F><><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD>
m_bRecvIng = false;
m_dwRecvTickCount = GetTickCount();
//<2F>жϹر<CFB9>
if (m_hSocket == INVALID_SOCKET)
{
CloseSocket(m_wRountID);
return true;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int iRetCode = recv(m_hSocket, (char *)m_cbRecvBuf + m_wRecvSize, sizeof(m_cbRecvBuf) - m_wRecvSize, 0);
if (iRetCode <= 0)
{
CloseSocket(m_wRountID);
return true;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m_wRecvSize += iRetCode;
BYTE cbBuffer[SOCKET_TCP_BUFFER];
TCP_Head * pHead = (TCP_Head *)m_cbRecvBuf;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
try
{
while (m_wRecvSize >= sizeof(TCP_Head))
{
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
WORD wPacketSize = pHead->TCPInfo.wPacketSize;
if (wPacketSize > SOCKET_TCP_BUFFER) throw TEXT("<EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
if (wPacketSize < sizeof(TCP_Head)) throw TEXT("<EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><EFBFBD>Ƿ<EFBFBD>");
//if (pHead->TCPInfo.cbVersion != SOCKET_TCP_VER) throw TEXT("<22><><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><E6B1BE><EFBFBD><EFBFBD>");
if (pHead->TCPInfo.cbDataKind != DK_MAPPED) throw TEXT("<EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
if (m_wRecvSize < wPacketSize) break;
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
CopyMemory(cbBuffer, m_cbRecvBuf, wPacketSize);
WORD wRealySize = CrevasseBuffer(cbBuffer, wPacketSize);
ASSERT(wRealySize >= sizeof(TCP_Head));
m_dwRecvPacketCount++;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
WORD wDataSize = wRealySize - sizeof(TCP_Head);
void * pDataBuffer = cbBuffer + sizeof(TCP_Head);
TCP_Command Command = ((TCP_Head *)cbBuffer)->CommandInfo;
//<2F>ں<EFBFBD><DABA><EFBFBD><EFBFBD><EFBFBD>
if (Command.wMainCmdID == MDM_KN_COMMAND)
{
switch (Command.wSubCmdID)
{
case SUB_KN_DETECT_SOCKET: //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
break;
}
case SUB_KN_VALIDATE_SOCKET:
{
break;
}
default:
{
throw TEXT("<EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
}
}
}
else
{
//<2F><>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>
m_pIServerSocketItemSink->OnSocketReadEvent(Command, pDataBuffer, wDataSize, this);
}
//ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m_wRecvSize -= wPacketSize;
MoveMemory(m_cbRecvBuf, m_cbRecvBuf + wPacketSize, m_wRecvSize);
}
}
catch (LPCTSTR strExp)
{
::OutputDebugString(strExp);
CloseSocket(m_wRountID);
return false;
}
catch (...)
{
CloseSocket(m_wRountID);
return false;
}
return RecvData();
}
//<2F>ر<EFBFBD><D8B1><EFBFBD><EFBFBD><EFBFBD>֪ͨ
bool CServerSocketItem::OnCloseCompleted()
{
//Ч<><D0A7>״̬
ASSERT(m_hSocket == INVALID_SOCKET);
ASSERT(m_OverLappedSendActive.GetCount() == 0);
//<2F>ر<EFBFBD><D8B1>¼<EFBFBD>
ASSERT(m_bNotify == false);
if (m_bNotify == false)
{
m_bNotify = true;
m_pIServerSocketItemSink->OnSocketCloseEvent(this);
}
//״̬<D7B4><CCAC><EFBFBD><EFBFBD>
ResetSocketData();
return true;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
WORD CServerSocketItem::EncryptBuffer(BYTE pcbDataBuffer[], WORD wDataSize, WORD wBufferSize)
{
WORD i = 0;
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ASSERT(wDataSize >= sizeof(TCP_Head));
ASSERT(wDataSize <= (sizeof(TCP_Head) + SOCKET_TCP_BUFFER));
ASSERT(wBufferSize >= (wDataSize + 2*sizeof(DWORD)));
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
WORD wEncryptSize = wDataSize - sizeof(TCP_Info), wSnapCount = 0;
if ((wEncryptSize % sizeof(DWORD)) != 0)
{
wSnapCount = sizeof(DWORD) - wEncryptSize % sizeof(DWORD);
memset(pcbDataBuffer + sizeof(TCP_Info) + wEncryptSize, 0, wSnapCount);
}
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>ӳ<EFBFBD><D3B3>
BYTE cbCheckCode = 0;
for (i = sizeof(TCP_Info); i < wDataSize; i++)
{
cbCheckCode += pcbDataBuffer[i];
pcbDataBuffer[i] = MapSendByte(pcbDataBuffer[i]);
}
//<2F><>д<EFBFBD><D0B4>Ϣͷ
TCP_Head * pHead = (TCP_Head *)pcbDataBuffer;
pHead->TCPInfo.cbCheckCode = ~cbCheckCode + 1;
pHead->TCPInfo.wPacketSize = wDataSize;
//pHead->TCPInfo.cbVersion = SOCKET_TCP_VER;
pHead->TCPInfo.cbDataKind = DK_MAPPED;
////<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//DWORD dwXorKey = m_dwSendXorKey;
//WORD * pwSeed = (WORD *)(pcbDataBuffer + sizeof(TCP_Info));
//DWORD * pdwXor = (DWORD *)(pcbDataBuffer + sizeof(TCP_Info));
//WORD wEncrypCount = (wEncryptSize + wSnapCount) / sizeof(DWORD);
//for (i = 0; i < wEncrypCount; i++)
//{
// *pdwXor++ ^= dwXorKey;
// dwXorKey = SeedRandMap(*pwSeed++);
// dwXorKey |= ((DWORD)SeedRandMap(*pwSeed++)) << 16;
// dwXorKey ^= g_dwPacketKey;
//}
//<2F><><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD>
m_dwSendPacketCount++;
//m_dwSendXorKey = dwXorKey;
return wDataSize;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
WORD CServerSocketItem::CrevasseBuffer(BYTE pcbDataBuffer[], WORD wDataSize)
{
WORD i = 0;
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ASSERT(wDataSize >= sizeof(TCP_Head));
ASSERT(((TCP_Head *)pcbDataBuffer)->TCPInfo.wPacketSize == wDataSize);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
WORD wSnapCount = 0;
if ((wDataSize % sizeof(DWORD)) != 0)
{
wSnapCount = sizeof(DWORD) - wDataSize % sizeof(DWORD);
memset(pcbDataBuffer + wDataSize, 0, wSnapCount);
}
////<2F><>ȡ<EFBFBD><C8A1>Կ
//if (m_dwRecvPacketCount == 0)
//{
// ASSERT(wDataSize >= (sizeof(TCP_Head) + sizeof(DWORD)));
// if (wDataSize < (sizeof(TCP_Head) + sizeof(DWORD))) throw TEXT("<22><><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD>ܳ<EFBFBD><DCB3>ȴ<EFBFBD><C8B4><EFBFBD>");
// m_dwRecvXorKey = *(DWORD *)(pcbDataBuffer + sizeof(TCP_Head));
// m_dwSendXorKey = m_dwRecvXorKey;
// MoveMemory(pcbDataBuffer + sizeof(TCP_Head), pcbDataBuffer + sizeof(TCP_Head) + sizeof(DWORD),
// wDataSize - sizeof(TCP_Head) - sizeof(DWORD));
// wDataSize -= sizeof(DWORD);
// ((TCP_Head *)pcbDataBuffer)->TCPInfo.wPacketSize -= sizeof(DWORD);
//}
////<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//DWORD dwXorKey = m_dwRecvXorKey;
//DWORD * pdwXor = (DWORD *)(pcbDataBuffer + sizeof(TCP_Info));
//WORD * pwSeed = (WORD *)(pcbDataBuffer + sizeof(TCP_Info));
//WORD wEncrypCount = (wDataSize + wSnapCount - sizeof(TCP_Info)) / 4;
//for (i = 0; i < wEncrypCount; i++)
//{
// if ((i == (wEncrypCount - 1)) && (wSnapCount > 0))
// {
// BYTE * pcbKey = ((BYTE *) & m_dwRecvXorKey) + sizeof(DWORD) - wSnapCount;
// CopyMemory(pcbDataBuffer + wDataSize, pcbKey, wSnapCount);
// }
// dwXorKey = SeedRandMap(*pwSeed++);
// dwXorKey |= ((DWORD)SeedRandMap(*pwSeed++)) << 16;
// dwXorKey ^= g_dwPacketKey;
// *pdwXor++ ^= m_dwRecvXorKey;
// m_dwRecvXorKey = dwXorKey;
//}
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>ӳ<EFBFBD><D3B3>
TCP_Head * pHead = (TCP_Head *)pcbDataBuffer;
BYTE cbCheckCode = pHead->TCPInfo.cbCheckCode;;
for (i = sizeof(TCP_Info); i < wDataSize; i++)
{
pcbDataBuffer[i] = MapRecvByte(pcbDataBuffer[i]);
cbCheckCode += pcbDataBuffer[i];
}
if (cbCheckCode != 0)
{
throw TEXT("<EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD>Ч<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
}
return wDataSize;
}
//////////////////////////////////////////////////////////////////////////
//<2F><><EFBFBD><EFBFBD><ECBAAF>
CServerSocketRSThread::CServerSocketRSThread(void)
{
m_hCompletionPort = NULL;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CServerSocketRSThread::~CServerSocketRSThread(void)
{
}
//<2F><><EFBFBD>ú<EFBFBD><C3BA><EFBFBD>
bool CServerSocketRSThread::InitThread(HANDLE hCompletionPort)
{
ASSERT(hCompletionPort != NULL);
m_hCompletionPort = hCompletionPort;
return true;
}
//<2F><><EFBFBD>к<EFBFBD><D0BA><EFBFBD>
bool CServerSocketRSThread::OnEventThreadRun()
{
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ASSERT(m_hCompletionPort != NULL);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
DWORD dwThancferred = 0;
OVERLAPPED * pOverLapped = NULL;
COverLapped * pSocketLapped = NULL;
CServerSocketItem * pServerSocketItem = NULL;
//<2F>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD>ɶ˿<C9B6>
BOOL bSuccess = GetQueuedCompletionStatus(m_hCompletionPort, &dwThancferred, (PULONG_PTR) & pServerSocketItem, &pOverLapped, INFINITE);
if ((bSuccess == FALSE) && (GetLastError() != ERROR_NETNAME_DELETED)) return false;
if ((pServerSocketItem == NULL) && (pOverLapped == NULL)) return false;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ASSERT(pOverLapped != NULL);
ASSERT(pServerSocketItem != NULL);
pSocketLapped = CONTAINING_RECORD(pOverLapped, COverLapped, m_OverLapped);
switch (pSocketLapped->GetOperationType())
{
case OperationType_Recv: //SOCKET <20><><EFBFBD>ݶ<EFBFBD>ȡ
{
COverLappedRecv * pOverLappedRecv = (COverLappedRecv *)pSocketLapped;
CWHDataLocker lock(pServerSocketItem->GetSignedLock());
pServerSocketItem->OnRecvCompleted(pOverLappedRecv, dwThancferred);
break;
}
case OperationType_Send: //SOCKET <20><><EFBFBD>ݷ<EFBFBD><DDB7><EFBFBD>
{
COverLappedSend * pOverLappedSend = (COverLappedSend *)pSocketLapped;
CWHDataLocker lock(pServerSocketItem->GetSignedLock());
pServerSocketItem->OnSendCompleted(pOverLappedSend, dwThancferred);
break;
}
}
return true;
}
//////////////////////////////////////////////////////////////////////////
//<2F><><EFBFBD><EFBFBD><ECBAAF>
CSocketAcceptThread::CSocketAcceptThread(void)
{
m_hCompletionPort = NULL;
m_pTCPSocketManager = NULL;
m_hListenSocket = INVALID_SOCKET;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CSocketAcceptThread::~CSocketAcceptThread(void)
{
}
//<2F><><EFBFBD>ú<EFBFBD><C3BA><EFBFBD>
bool CSocketAcceptThread::InitThread(HANDLE hCompletionPort, SOCKET hListenSocket, CTCPNetworkEngine * pTCPSocketManager)
{
ASSERT(hCompletionPort != NULL);
ASSERT(pTCPSocketManager != NULL);
ASSERT(hListenSocket != INVALID_SOCKET);
m_hListenSocket = hListenSocket;
m_hCompletionPort = hCompletionPort;
m_pTCPSocketManager = pTCPSocketManager;
return true;
}
//<2F><><EFBFBD>к<EFBFBD><D0BA><EFBFBD>
bool CSocketAcceptThread::OnEventThreadRun()
{
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ASSERT(m_hCompletionPort != NULL);
ASSERT(m_pTCPSocketManager != NULL);
//<2F><><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD>
SOCKADDR_IN SocketAddr;
CServerSocketItem * pServerSocketItem = NULL;
SOCKET hConnectSocket = INVALID_SOCKET;
int nBufferSize = sizeof(SocketAddr);
try
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
hConnectSocket = WSAAccept(m_hListenSocket, (SOCKADDR *) & SocketAddr, &nBufferSize, NULL, NULL);
if (hConnectSocket == INVALID_SOCKET) return false;
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
pServerSocketItem = m_pTCPSocketManager->ActiveSocketItem();
if (pServerSocketItem == NULL) throw TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>");
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CWHDataLocker lock(pServerSocketItem->GetSignedLock());
pServerSocketItem->Attach(hConnectSocket, SocketAddr.sin_addr.S_un.S_addr);
CreateIoCompletionPort((HANDLE)hConnectSocket, m_hCompletionPort, (ULONG_PTR)pServerSocketItem, 0);
pServerSocketItem->RecvData();
}
catch (...)
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ASSERT(pServerSocketItem == NULL);
if (hConnectSocket != INVALID_SOCKET) closesocket(hConnectSocket);
}
return true;
}
//////////////////////////////////////////////////////////////////////////
//<2F><><EFBFBD><EFBFBD><ECBAAF>
CSocketDetectThread::CSocketDetectThread(void)
{
m_dwTickCount = 0;;
m_pTCPSocketManager = NULL;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CSocketDetectThread::~CSocketDetectThread(void)
{
}
//<2F><><EFBFBD>ú<EFBFBD><C3BA><EFBFBD>
bool CSocketDetectThread::InitThread(CTCPNetworkEngine * pTCPSocketManager)
{
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ASSERT(pTCPSocketManager != NULL);
//<2F><><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD>
m_dwTickCount = 0L;
m_pTCPSocketManager = pTCPSocketManager;
return true;
}
//<2F><><EFBFBD>к<EFBFBD><D0BA><EFBFBD>
bool CSocketDetectThread::OnEventThreadRun()
{
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ASSERT(m_pTCPSocketManager != NULL);
//<2F><><EFBFBD>ü<EFBFBD><C3BC><EFBFBD>
Sleep(500);
m_dwTickCount += 500L;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (m_dwTickCount > TIME_DETECT_SOCKET)
{
m_dwTickCount = 0L;
m_pTCPSocketManager->DetectSocket();
}
return true;
}
//////////////////////////////////////////////////////////////////////////
//<2F><><EFBFBD><EFBFBD><ECBAAF>
CTCPNetworkEngine::CTCPNetworkEngine(void)
{
m_bService = false;
m_wListenPort = 0;
m_dwLastDetect = 0;
m_wMaxSocketItem = 0;
m_hCompletionPort = NULL;
m_hServerSocket = INVALID_SOCKET;
return;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CTCPNetworkEngine::~CTCPNetworkEngine(void)
{
//ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD>
ConcludeService();
//<2F>ͷŴ洢<C5B4><E6B4A2><EFBFBD><EFBFBD>
CServerSocketItem * pSocketItem = NULL;
for (INT_PTR i = 0; i < m_StorageSocketItem.GetCount(); i++)
{
pSocketItem = m_StorageSocketItem[i];
ASSERT(pSocketItem != NULL);
SafeDelete(pSocketItem);
}
m_StorageSocketItem.RemoveAll();
return;
}
//<2F>ӿڲ<D3BF>ѯ
void * CTCPNetworkEngine::QueryInterface(const IID & Guid, DWORD dwQueryVer)
{
QUERYINTERFACE(ITCPNetworkEngine, Guid, dwQueryVer);
QUERYINTERFACE(IQueueServiceSink, Guid, dwQueryVer);
QUERYINTERFACE_IUNKNOWNEX(ITCPNetworkEngine, Guid, dwQueryVer);
return NULL;
}
//<2F><><EFBFBD>ö˿<C3B6>
WORD CTCPNetworkEngine::GetServicePort()
{
return m_wListenPort;
}
//<2F><>ǰ<EFBFBD>˿<EFBFBD>
WORD CTCPNetworkEngine::GetCurrentPort()
{
return m_wListenPort;
}
//<2F><><EFBFBD>ýӿ<C3BD>
bool CTCPNetworkEngine::SetTCPNetworkEngineEvent(IUnknownEx * pIUnknownEx)
{
//״̬<D7B4>ж<EFBFBD>
if (m_bService == true)
{
CTraceService::TraceString(TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڷ<EFBFBD><EFBFBD><EFBFBD>״̬<EFBFBD><EFBFBD><EFBFBD>󶨲<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"), TraceLevel_Exception);
return false;
}
//<2F><><EFBFBD>ýӿ<C3BD>
if (m_QueueServiceEvent.SetQueueServiceSink(pIUnknownEx) == false)
{
CTraceService::TraceString(TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>"), TraceLevel_Exception);
return false;
}
return true;
}
//<2F><><EFBFBD>ò<EFBFBD><C3B2><EFBFBD>
bool CTCPNetworkEngine::SetServiceParameter(WORD wServicePort, WORD wMaxConnect, LPCTSTR pszCompilation)
{
//Ч<><D0A7>״̬
if (m_bService == true)
{
CTraceService::TraceString(TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڷ<EFBFBD><EFBFBD><EFBFBD>״̬<EFBFBD><EFBFBD><EFBFBD>˿ڰ󶨲<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"), TraceLevel_Exception);
return false;
}
//<2F>жϲ<D0B6><CFB2><EFBFBD>
if (wServicePort == 0)
{
CTraceService::TraceString(TEXT("δָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˿ڣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"), TraceLevel_Normal);
}
//<2F><><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD>
m_wListenPort = wServicePort;
m_wMaxSocketItem = wMaxConnect;
return true;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool CTCPNetworkEngine::StartService()
{
DWORD i = 0;
//Ч<><D0A7>״̬
if (m_bService == true)
{
CTraceService::TraceString(TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"), TraceLevel_Warning);
return true;
}
//<2F>󶨶<EFBFBD><F3B6A8B6><EFBFBD>
if (m_SendQueueService.SetQueueServiceSink(QUERY_ME_INTERFACE(IUnknownEx)) == false)
{
CTraceService::TraceString(TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>"), TraceLevel_Exception);
return false;
}
try
{
//<2F><>ȡϵͳ<CFB5><CDB3>Ϣ
SYSTEM_INFO SystemInfo;
GetSystemInfo(&SystemInfo);
DWORD dwThreadCount = SystemInfo.dwNumberOfProcessors;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɶ˿<C9B6>
m_hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, SystemInfo.dwNumberOfProcessors);
if (m_hCompletionPort == NULL) throw TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɶ˿ڴ<EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>");
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SOCKET
struct sockaddr_in SocketAddr;
memset(&SocketAddr, 0, sizeof(SocketAddr));
SocketAddr.sin_addr.s_addr = INADDR_ANY;
SocketAddr.sin_family = AF_INET;
SocketAddr.sin_port = htons(m_wListenPort);
m_hServerSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
if (m_hServerSocket == INVALID_SOCKET) throw TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> SOCKET <20><><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>");
int iErrorCode = bind(m_hServerSocket, (SOCKADDR*) & SocketAddr, sizeof(SocketAddr));
if (iErrorCode == SOCKET_ERROR) throw TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˿ڱ<EFBFBD>ռ<EFBFBD>ã<EFBFBD><EFBFBD>˿ڰ<EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>");
iErrorCode = listen(m_hServerSocket, 200);
if (iErrorCode == SOCKET_ERROR) throw TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˿ڱ<EFBFBD>ռ<EFBFBD>ã<EFBFBD><EFBFBD>˿ڼ<EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>");
//<2F><>ȡ<EFBFBD>˿<EFBFBD>
int iLen=sizeof(SocketAddr);
getsockname(m_hServerSocket,(SOCKADDR*) & SocketAddr, &iLen);
m_wListenPort=htons(SocketAddr.sin_port);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD>
bool bSuccess = m_SendQueueService.StartService();
if (bSuccess == false) throw TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͷ<EFBFBD><EFBFBD>з<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>");
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD>߳<EFBFBD>
for (i = 0; i < dwThreadCount; i++)
{
CServerSocketRSThread * pServerSocketRSThread = new CServerSocketRSThread();
if (pServerSocketRSThread == NULL) throw TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD>̷߳<EFBFBD><EFBFBD>񴴽<EFBFBD>ʧ<EFBFBD><EFBFBD>");
bSuccess = pServerSocketRSThread->InitThread(m_hCompletionPort);
if (bSuccess == false) throw TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD>̷߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>");
m_SocketRSThreadArray.Add(pServerSocketRSThread);
}
//<2F><><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD>߳<EFBFBD>
bSuccess = m_SocketAcceptThread.InitThread(m_hCompletionPort, m_hServerSocket, this);
if (bSuccess == false) throw TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̷߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
//<2F><><EFBFBD>ж<EFBFBD>д<EFBFBD>߳<EFBFBD>
for (i = 0; i < dwThreadCount; i++)
{
CServerSocketRSThread * pServerSocketRSThread = m_SocketRSThreadArray[i];
ASSERT(pServerSocketRSThread != NULL);
bSuccess = pServerSocketRSThread->StartThread();
if (bSuccess == false) throw TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD>̷߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>");
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
m_SocketDetectThread.InitThread(this);
bSuccess = m_SocketDetectThread.StartThread();
if (bSuccess == false) throw TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̷߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>");
//<2F><><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD>߳<EFBFBD>
bSuccess = m_SocketAcceptThread.StartThread();
if (bSuccess == false) throw TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̷߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>");
//<2F><><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD>
m_bService = true;
}
catch (LPCTSTR pszError)
{
CTraceService::TraceString(pszError, TraceLevel_Exception);
return false;
}
return true;
}
//ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD>
bool CTCPNetworkEngine::ConcludeService()
{
//<2F><><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD>
m_bService = false;
m_dwLastDetect = 0L;
//ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
m_SocketDetectThread.ConcludeThread(INFINITE);
//<2F><>ֹӦ<D6B9><D3A6><EFBFBD>߳<EFBFBD>
if (m_hServerSocket != INVALID_SOCKET)
{
closesocket(m_hServerSocket);
m_hServerSocket = INVALID_SOCKET;
}
m_SocketAcceptThread.ConcludeThread(INFINITE);
//ֹͣ<CDA3><D6B9><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD>
m_SendQueueService.ConcludeService();
//<2F>ͷŶ<CDB7>д<EFBFBD>߳<EFBFBD>
INT_PTR nCount = m_SocketRSThreadArray.GetCount(), i = 0;
if (m_hCompletionPort != NULL)
{
for (i = 0; i < nCount; i++) PostQueuedCompletionStatus(m_hCompletionPort, 0, NULL, NULL);
}
for (i = 0; i < nCount; i++)
{
CServerSocketRSThread * pSocketThread = m_SocketRSThreadArray[i];
ASSERT(pSocketThread != NULL);
pSocketThread->ConcludeThread(INFINITE);
SafeDelete(pSocketThread);
}
m_SocketRSThreadArray.RemoveAll();
//<2F>ر<EFBFBD><D8B1><EFBFBD><EFBFBD>ɶ˿<C9B6>
if (m_hCompletionPort != NULL)
{
CloseHandle(m_hCompletionPort);
m_hCompletionPort = NULL;
}
//<2F>ر<EFBFBD><D8B1><EFBFBD><EFBFBD><EFBFBD>
CServerSocketItem * pServerSocketItem = NULL;
for (i = 0; i < m_ActiveSocketItem.GetCount(); i++)
{
pServerSocketItem = m_ActiveSocketItem[i];
ASSERT(pServerSocketItem != NULL);
pServerSocketItem->CloseSocket(pServerSocketItem->GetRountID());
pServerSocketItem->ResetSocketData();
}
m_FreeSocketItem.Append(m_ActiveSocketItem);
m_ActiveSocketItem.RemoveAll();
m_QueueServiceEvent.SetQueueServiceSink(NULL);
return true;
}
//Ӧ<><D3A6><EFBFBD><EFBFBD>Ϣ
bool CTCPNetworkEngine::OnSocketAcceptEvent(CServerSocketItem * pServerSocketItem)
{
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ASSERT(pServerSocketItem != NULL);
if (NULL == pServerSocketItem) return false;
//Ͷ<><CDB6><EFBFBD><EFBFBD>Ϣ
if (m_bService == false) return false;
m_QueueServiceEvent.PostNetworkAcceptEvent(pServerSocketItem->GetSocketID(), pServerSocketItem->GetClientAddr());
return true;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>Ϣ
bool CTCPNetworkEngine::OnSocketReadEvent(TCP_Command Command, void * pBuffer, WORD wDataSize, CServerSocketItem * pServerSocketItem)
{
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ASSERT(pServerSocketItem != NULL);
if (NULL == pServerSocketItem) return false;
//Ч<><D0A7>״̬
if (m_bService == false) return false;
m_QueueServiceEvent.PostNetworkReadEvent(pServerSocketItem->GetSocketID(), Command, pBuffer, wDataSize);
return true;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><D8B1><EFBFBD>Ϣ
bool CTCPNetworkEngine::OnSocketCloseEvent(CServerSocketItem * pServerSocketItem)
{
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ASSERT(pServerSocketItem != NULL);
if (NULL == pServerSocketItem) return false;
try
{
//Ч<><D0A7>״̬
if (m_bService == false) return false;
//<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
WORD wIndex = pServerSocketItem->GetIndex();
WORD wRountID = pServerSocketItem->GetRountID();
DWORD dwClientAddr = pServerSocketItem->GetClientAddr();
DWORD dwConnectTime = pServerSocketItem->GetConnectTime();
//////////////////////////////////////////////////////////////////////////,<2C><><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>
m_QueueServiceEvent.PostNetworkShutEvent(pServerSocketItem->GetSocketID() , dwClientAddr, dwConnectTime);
//<2F>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD>
FreeSocketItem(pServerSocketItem);
}
catch (...) {}
return true;
}
//֪ͨ<CDA8>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD><EFBFBD>̵߳<DFB3><CCB5>ã<EFBFBD>
void CTCPNetworkEngine::OnQueueServiceSink(WORD wIdentifier, void * pBuffer, WORD wDataSize)
{
switch (wIdentifier)
{
case QUEUE_SEND_REQUEST: //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tagSendDataRequest * pSendDataRequest = (tagSendDataRequest *)pBuffer;
ASSERT(wDataSize >= (sizeof(tagSendDataRequest) - sizeof(pSendDataRequest->cbSendBuf)));
ASSERT(wDataSize == (pSendDataRequest->wDataSize + sizeof(tagSendDataRequest) - sizeof(pSendDataRequest->cbSendBuf)));
//Ⱥ<><C8BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (pSendDataRequest->dwSocketID == 0)
{
//<2F><>ȡ<EFBFBD><EFBFBD><EEB6AF>
{
CWHDataLocker lcok(m_CriticalSection);
m_TempSocketItem.RemoveAll();
m_TempSocketItem.Copy(m_ActiveSocketItem);
}
//ѭ<><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CServerSocketItem * pServerSocketItem = NULL;
for (INT_PTR i = 0; i < m_TempSocketItem.GetCount(); i++)
{
pServerSocketItem = m_TempSocketItem[i];
ASSERT(pServerSocketItem != NULL);
CWHDataLocker lock(pServerSocketItem->GetSignedLock());
if (pServerSocketItem->IsAllowBatch())//<2F><>һ<EFBFBD>β<EFBFBD><CEB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
pServerSocketItem->SendData(pSendDataRequest->cbSendBuf, pSendDataRequest->wDataSize, pSendDataRequest->wMainCmdID,
pSendDataRequest->wSubCmdID, pServerSocketItem->GetRountID());
}
}
}
else
{
//<2F><><EFBFBD><EFBFBD><EEB7A2>
CServerSocketItem * pServerSocketItem = EnumSocketItem(LOWORD(pSendDataRequest->dwSocketID));
CWHDataLocker lock(pServerSocketItem->GetSignedLock());
pServerSocketItem->SendData(pSendDataRequest->cbSendBuf, pSendDataRequest->wDataSize, pSendDataRequest->wMainCmdID,
pSendDataRequest->wSubCmdID, HIWORD(pSendDataRequest->dwSocketID));
}
break;
}
case QUEUE_SAFE_CLOSE: //<2F><>ȫ<EFBFBD>ر<EFBFBD>
{
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ASSERT(wDataSize == sizeof(tagSafeCloseSocket));
tagSafeCloseSocket * pSafeCloseSocket = (tagSafeCloseSocket *)pBuffer;
//<2F><>ȫ<EFBFBD>ر<EFBFBD>
try
{
CServerSocketItem * pServerSocketItem = EnumSocketItem(LOWORD(pSafeCloseSocket->dwSocketID));
CWHDataLocker lock(pServerSocketItem->GetSignedLock());
pServerSocketItem->ShutDownSocket(HIWORD(pSafeCloseSocket->dwSocketID));
}
catch (...)
{
}
break;
}
case QUEUE_ALLOW_BATCH: //<2F><><EFBFBD><EFBFBD>Ⱥ<EFBFBD><C8BA>
{
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ASSERT(wDataSize == sizeof(tagAllowBatchSend));
tagAllowBatchSend * pAllowBatchSend = (tagAllowBatchSend *)pBuffer;
//<2F><><EFBFBD><EFBFBD>Ⱥ<EFBFBD><C8BA>
CServerSocketItem * pServerSocketItem = EnumSocketItem(LOWORD(pAllowBatchSend->dwSocketID));
CWHDataLocker lock(pServerSocketItem->GetSignedLock());
pServerSocketItem->AllowBatchSend(HIWORD(pAllowBatchSend->dwSocketID), pAllowBatchSend->cbAllow ? true : false);
break;
}
case QUEUE_DETECT_SOCKET: //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
//<2F><>ȡ<EFBFBD><EFBFBD><EEB6AF>
{
CWHDataLocker lcok(m_CriticalSection);
m_TempSocketItem.RemoveAll();
m_TempSocketItem.Copy(m_ActiveSocketItem);
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TCP_KN_DetectSocket DetectSocket;
ZeroMemory(&DetectSocket, sizeof(DetectSocket));
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
WORD wRountID = 0;
DWORD dwNowTickCount = GetTickCount();
DWORD dwBreakTickCount = __max(dwNowTickCount - m_dwLastDetect, TIME_BREAK_READY);
//<2F><><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD>
m_dwLastDetect = GetTickCount();
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
for (INT_PTR i = 0; i < m_TempSocketItem.GetCount(); i++)
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CServerSocketItem * pServerSocketItem = m_TempSocketItem[i];
DWORD dwRecvTickCount = pServerSocketItem->GetRecvTickCount();
CWHDataLocker lock(pServerSocketItem->GetSignedLock());
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (dwRecvTickCount >= dwNowTickCount) continue;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (pServerSocketItem->IsReadySend() == true)
{
if ((dwNowTickCount - dwRecvTickCount) > dwBreakTickCount)
{
pServerSocketItem->CloseSocket(pServerSocketItem->GetRountID());
continue;
}
}
else
{
if ((dwNowTickCount - dwRecvTickCount) > TIME_BREAK_CONNECT)
{
pServerSocketItem->CloseSocket(pServerSocketItem->GetRountID());
continue;
}
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (pServerSocketItem->IsReadySend() == true)
{
wRountID = pServerSocketItem->GetRountID();
DetectSocket.dwSendTickCount = GetTickCount();
pServerSocketItem->SendData(&DetectSocket, sizeof(DetectSocket), MDM_KN_COMMAND, SUB_KN_DETECT_SOCKET, wRountID);
}
}
break;
}
default:
{
ASSERT(FALSE);
}
}
return;
}
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD>ж<EFBFBD><D0B6><EFBFBD>
CServerSocketItem * CTCPNetworkEngine::ActiveSocketItem()
{
CWHDataLocker lock(m_CriticalSection);
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD>ж<EFBFBD><D0B6><EFBFBD>
CServerSocketItem * pServerSocketItem = NULL;
if (m_FreeSocketItem.GetCount() > 0)
{
INT_PTR nItemPostion = m_FreeSocketItem.GetCount() - 1;
pServerSocketItem = m_FreeSocketItem[nItemPostion];
ASSERT(pServerSocketItem != NULL);
m_FreeSocketItem.RemoveAt(nItemPostion);
m_ActiveSocketItem.Add(pServerSocketItem);
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><C2B6><EFBFBD>
if (pServerSocketItem == NULL)
{
WORD wStorageCount = (WORD)m_StorageSocketItem.GetCount();
if (wStorageCount < m_wMaxSocketItem)
{
try
{
pServerSocketItem = new CServerSocketItem(wStorageCount, this);
if (pServerSocketItem == NULL) return NULL;
m_StorageSocketItem.Add(pServerSocketItem);
m_ActiveSocketItem.Add(pServerSocketItem);
}
catch (...)
{
return NULL;
}
}
}
return pServerSocketItem;
}
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD>
CServerSocketItem * CTCPNetworkEngine::EnumSocketItem(WORD wIndex)
{
CWHDataLocker lock(m_CriticalSection);
if (wIndex < m_StorageSocketItem.GetCount())
{
CServerSocketItem * pServerSocketItem = m_StorageSocketItem[wIndex];
ASSERT(pServerSocketItem != NULL);
return pServerSocketItem;
}
return NULL;
}
//<2F>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD>
bool CTCPNetworkEngine::FreeSocketItem(CServerSocketItem * pServerSocketItem)
{
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ASSERT(pServerSocketItem != NULL);
//<2F>ͷŶ<CDB7><C5B6><EFBFBD>
CWHDataLocker lock(m_CriticalSection);
INT_PTR nActiveCount = m_ActiveSocketItem.GetCount();
for (int i = 0; i < nActiveCount; i++)
{
if (pServerSocketItem == m_ActiveSocketItem[i])
{
m_ActiveSocketItem.RemoveAt(i);
m_FreeSocketItem.Add(pServerSocketItem);
return true;
}
}
//<2F>ͷ<EFBFBD>ʧ<EFBFBD><CAA7>
ASSERT(FALSE);
return false;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool CTCPNetworkEngine::DetectSocket()
{
return m_SendQueueService.AddToQueue(QUEUE_DETECT_SOCKET, NULL, 0);
}
//<2F><><EFBFBD>ͺ<EFBFBD><CDBA><EFBFBD>
bool CTCPNetworkEngine::SendData(DWORD dwSocketID, WORD wMainCmdID, WORD wSubCmdID)
{
//Ч<><D0A7>״̬
ASSERT(m_bService == true);
if (m_bService == false) return false;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tagSendDataRequest SendRequest;
SendRequest.wMainCmdID = wMainCmdID;
SendRequest.wSubCmdID = wSubCmdID;
SendRequest.dwSocketID = dwSocketID;
SendRequest.wDataSize = 0;
//<2F><><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD>
WORD wSendSize = sizeof(SendRequest) - sizeof(SendRequest.cbSendBuf);
return m_SendQueueService.AddToQueue(QUEUE_SEND_REQUEST, &SendRequest, wSendSize);
}
//<2F><><EFBFBD>ͺ<EFBFBD><CDBA><EFBFBD>
bool CTCPNetworkEngine::SendData(DWORD dwSocketID, WORD wMainCmdID, WORD wSubCmdID, void * pData, WORD wDataSize)
{
//Ч<><D0A7>״̬
ASSERT(m_bService == true);
if (m_bService == false) return false;
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ASSERT((wDataSize + sizeof(TCP_Head)) <= SOCKET_TCP_BUFFER);
if ((wDataSize + sizeof(TCP_Head)) > SOCKET_TCP_BUFFER) return false;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tagSendDataRequest SendRequest;
SendRequest.wMainCmdID = wMainCmdID;
SendRequest.wSubCmdID = wSubCmdID;
SendRequest.dwSocketID = dwSocketID;
SendRequest.wDataSize = wDataSize;
if (wDataSize > 0)
{
ASSERT(pData != NULL);
CopyMemory(SendRequest.cbSendBuf, pData, wDataSize);
}
//<2F><><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD>
WORD wSendSize = sizeof(SendRequest) - sizeof(SendRequest.cbSendBuf) + wDataSize;
return m_SendQueueService.AddToQueue(QUEUE_SEND_REQUEST, &SendRequest, wSendSize);
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool CTCPNetworkEngine::SendDataBatch(WORD wMainCmdID, WORD wSubCmdID, void * pData, WORD wDataSize, BYTE cbBatchMask)
{
//Ч<><D0A7>״̬
if (m_bService == false) return false;
//Ч<><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ASSERT((wDataSize + sizeof(TCP_Head)) <= SOCKET_TCP_BUFFER);
if ((wDataSize + sizeof(TCP_Head)) > SOCKET_TCP_BUFFER) return false;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tagSendDataRequest SendRequest;
SendRequest.wMainCmdID = wMainCmdID;
SendRequest.wSubCmdID = wSubCmdID;
SendRequest.dwSocketID = 0;
SendRequest.wDataSize = wDataSize;
if (wDataSize > 0)
{
ASSERT(pData != NULL);
CopyMemory(SendRequest.cbSendBuf, pData, wDataSize);
}
//<2F><><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD>
WORD wSendSize = sizeof(SendRequest) - sizeof(SendRequest.cbSendBuf) + wDataSize;
return m_SendQueueService.AddToQueue(QUEUE_SEND_REQUEST, &SendRequest, wSendSize);
}
//<2F>ر<EFBFBD><D8B1><EFBFBD><EFBFBD><EFBFBD>
bool CTCPNetworkEngine::CloseSocket(DWORD dwSocketID)
{
CServerSocketItem * pServerSocketItem = EnumSocketItem(LOWORD(dwSocketID));
if (pServerSocketItem == NULL) return false;
CWHDataLocker lock(pServerSocketItem->GetSignedLock());
return pServerSocketItem->CloseSocket(HIWORD(dwSocketID));
}
//<2F><><EFBFBD>ùر<C3B9>
bool CTCPNetworkEngine::ShutDownSocket(DWORD dwSocketID)
{
tagSafeCloseSocket SafeCloseSocket;
SafeCloseSocket.dwSocketID = dwSocketID;
return m_SendQueueService.AddToQueue(QUEUE_SAFE_CLOSE, &SafeCloseSocket, sizeof(SafeCloseSocket));
}
//<2F><><EFBFBD><EFBFBD>Ⱥ<EFBFBD><C8BA>
bool CTCPNetworkEngine::AllowBatchSend(DWORD dwSocketID, bool bAllow, BYTE cbBatchMask)
{
tagAllowBatchSend AllowBatchSendNode;
AllowBatchSendNode.dwSocketID = dwSocketID;
AllowBatchSendNode.cbAllow = bAllow;
return m_SendQueueService.AddToQueue(QUEUE_ALLOW_BATCH, &AllowBatchSendNode, sizeof(tagAllowBatchSend));
}
//////////////////////////////////////////////////////////////////////////
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
extern "C" __declspec(dllexport) void * CreateTCPNetworkEngine(const GUID & Guid, DWORD dwInterfaceVer)
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CTCPNetworkEngine * pTCPSocketEngine = NULL;
try
{
pTCPSocketEngine = new CTCPNetworkEngine();
if (pTCPSocketEngine == NULL) throw TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>");
void * pObject = pTCPSocketEngine->QueryInterface(Guid, dwInterfaceVer);
if (pObject == NULL) throw TEXT("<EFBFBD>ӿڲ<EFBFBD>ѯʧ<EFBFBD><EFBFBD>");
return pObject;
}
catch (...) {}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SafeDelete(pTCPSocketEngine);
return NULL;
}
//////////////////////////////////////////////////////////////////////////