mirror of
https://github.com/yuanyuanxiang/SimpleRemoter.git
synced 2026-01-21 23:13:08 +08:00
Improve: Reduce new / delete memory frequency in IOCPServer
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
#include "StdAfx.h"
|
||||
#include "StdAfx.h"
|
||||
#include "IOCPServer.h"
|
||||
#include "2015Remote.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> socket <EFBFBD><EFBFBD>ȡ<EFBFBD>ͻ<EFBFBD><EFBFBD><EFBFBD>IP<EFBFBD><EFBFBD>ַ.
|
||||
// 根据 socket 获取客户端IP地址.
|
||||
std::string GetPeerName(SOCKET sock)
|
||||
{
|
||||
sockaddr_in ClientAddr = {};
|
||||
@@ -14,7 +14,7 @@ std::string GetPeerName(SOCKET sock)
|
||||
return s != INVALID_SOCKET ? inet_ntoa(ClientAddr.sin_addr) : "";
|
||||
}
|
||||
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> socket <EFBFBD><EFBFBD>ȡ<EFBFBD>ͻ<EFBFBD><EFBFBD><EFBFBD>IP<EFBFBD><EFBFBD>ַ.
|
||||
// 根据 socket 获取客户端IP地址.
|
||||
std::string GetRemoteIP(SOCKET sock)
|
||||
{
|
||||
sockaddr_in addr;
|
||||
@@ -23,10 +23,10 @@ std::string GetRemoteIP(SOCKET sock)
|
||||
if (getpeername(sock, (sockaddr*)&addr, &addrLen) == 0) {
|
||||
char ipStr[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &addr.sin_addr, ipStr, sizeof(ipStr));
|
||||
TRACE(">>> <EFBFBD>Զ<EFBFBD> IP <EFBFBD><EFBFBD>ַ: %s\n", ipStr);
|
||||
TRACE(">>> 对端 IP 地址: %s\n", ipStr);
|
||||
return ipStr;
|
||||
}
|
||||
TRACE(">>> <EFBFBD><EFBFBD>ȡ<EFBFBD>Զ<EFBFBD> IP ʧ<><CAA7>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: %d\n", WSAGetLastError());
|
||||
TRACE(">>> 获取对端 IP 失败, 错误码: %d\n", WSAGetLastError());
|
||||
char buf[10];
|
||||
sprintf_s(buf, "%d", sock);
|
||||
return buf;
|
||||
@@ -108,7 +108,7 @@ IOCPServer::~IOCPServer(void)
|
||||
|
||||
while (!m_ContextFreePoolList.IsEmpty()) {
|
||||
CONTEXT_OBJECT *ContextObject = m_ContextFreePoolList.RemoveHead();
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD>2019.1.14
|
||||
// 下述语句有崩溃概率,2019.1.14
|
||||
//SAFE_DELETE(ContextObject->olps);
|
||||
delete ContextObject;
|
||||
}
|
||||
@@ -127,7 +127,7 @@ IOCPServer::~IOCPServer(void)
|
||||
WSACleanup();
|
||||
}
|
||||
|
||||
// <EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ.
|
||||
// 返回错误码0代表成功,否则代表错误信息.
|
||||
UINT IOCPServer::StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, USHORT uPort)
|
||||
{
|
||||
m_nPort = uPort;
|
||||
@@ -139,7 +139,7 @@ UINT IOCPServer::StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, U
|
||||
return 1;
|
||||
}
|
||||
|
||||
m_sListenSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
m_sListenSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED); //创建监听套接字
|
||||
|
||||
if (m_sListenSocket == INVALID_SOCKET) {
|
||||
return 2;
|
||||
@@ -154,7 +154,7 @@ UINT IOCPServer::StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, U
|
||||
return 3;
|
||||
}
|
||||
|
||||
int iRet = WSAEventSelect(m_sListenSocket, //<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>FD_ACCEPT<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
int iRet = WSAEventSelect(m_sListenSocket, //将监听套接字与事件进行关联并授予FD_ACCEPT的属性
|
||||
m_hListenEvent,
|
||||
FD_ACCEPT);
|
||||
|
||||
@@ -173,9 +173,9 @@ UINT IOCPServer::StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, U
|
||||
SOCKADDR_IN ServerAddr;
|
||||
ServerAddr.sin_port = htons(uPort);
|
||||
ServerAddr.sin_family = AF_INET;
|
||||
ServerAddr.sin_addr.s_addr = INADDR_ANY; //<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
ServerAddr.sin_addr.s_addr = INADDR_ANY; //初始化本地网卡
|
||||
|
||||
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֺ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>bind
|
||||
//将监听套机字和网卡进行bind
|
||||
iRet = bind(m_sListenSocket,
|
||||
(sockaddr*)&ServerAddr,
|
||||
sizeof(ServerAddr));
|
||||
@@ -210,7 +210,7 @@ UINT IOCPServer::StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, U
|
||||
(HANDLE)CreateThread(NULL,
|
||||
0,
|
||||
ListenThreadProc,
|
||||
(void*)this, //<EFBFBD><EFBFBD>Thread<EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>this <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǵ<EFBFBD><C7B5>̻߳ص<CCBB><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>еij<D0B5>Ա
|
||||
(void*)this, //向Thread回调函数传入this 方便我们的线程回调访问类中的成员
|
||||
0,
|
||||
NULL);
|
||||
if (m_hListenThread==NULL) {
|
||||
@@ -224,14 +224,14 @@ UINT IOCPServer::StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, U
|
||||
return a;
|
||||
}
|
||||
|
||||
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD> 1 2
|
||||
//启动工作线程 1 2
|
||||
InitializeIOCP();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//1<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɶ˿<EFBFBD>
|
||||
//2<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
|
||||
//1创建完成端口
|
||||
//2创建工作线程
|
||||
BOOL IOCPServer::InitializeIOCP(VOID)
|
||||
{
|
||||
m_hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0 );
|
||||
@@ -244,7 +244,7 @@ BOOL IOCPServer::InitializeIOCP(VOID)
|
||||
}
|
||||
|
||||
SYSTEM_INFO SystemInfo;
|
||||
GetSystemInfo(&SystemInfo); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>PC<EFBFBD><EFBFBD><EFBFBD>м<EFBFBD><EFBFBD><EFBFBD>
|
||||
GetSystemInfo(&SystemInfo); //获得PC中有几核
|
||||
|
||||
m_ulThreadPoolMin = 1;
|
||||
m_ulThreadPoolMax = SystemInfo.dwNumberOfProcessors * 2;
|
||||
@@ -255,7 +255,7 @@ BOOL IOCPServer::InitializeIOCP(VOID)
|
||||
|
||||
HANDLE hWorkThread = NULL;
|
||||
for (int i=0; i<ulWorkThreadCount; ++i) {
|
||||
hWorkThread = (HANDLE)CreateThread(NULL, //<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>
|
||||
hWorkThread = (HANDLE)CreateThread(NULL, //创建工作线程目的是处理投递到完成端口中的任务
|
||||
0,
|
||||
WorkThreadProc,
|
||||
(void*)this,
|
||||
@@ -279,7 +279,7 @@ DWORD IOCPServer::WorkThreadProc(LPVOID lParam)
|
||||
{
|
||||
Mprintf("======> IOCPServer WorkThreadProc begin \n");
|
||||
|
||||
ZSTD_DCtx* m_Dctx = ZSTD_createDCtx(); // <EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
ZSTD_DCtx* m_Dctx = ZSTD_createDCtx(); // 解压上下文
|
||||
|
||||
IOCPServer* This = (IOCPServer*)(lParam);
|
||||
|
||||
@@ -297,7 +297,7 @@ DWORD IOCPServer::WorkThreadProc(LPVOID lParam)
|
||||
timeBeginPeriod(1);
|
||||
while (This->m_bTimeToKill==FALSE) {
|
||||
InterlockedDecrement(&This->m_ulBusyThread);
|
||||
// GetQueuedCompletionStatus<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>
|
||||
// GetQueuedCompletionStatus耗时比较长,导致客户端发送数据的速率提高不了
|
||||
BOOL bOk = GetQueuedCompletionStatus(
|
||||
hCompletionPort,
|
||||
&dwTrans,
|
||||
@@ -306,7 +306,7 @@ DWORD IOCPServer::WorkThreadProc(LPVOID lParam)
|
||||
DWORD dwIOError = GetLastError();
|
||||
OverlappedPlus = CONTAINING_RECORD(Overlapped, OVERLAPPEDPLUS, m_ol);
|
||||
ulBusyThread = InterlockedIncrement(&This->m_ulBusyThread); //1 1
|
||||
if ( !bOk && dwIOError != WAIT_TIMEOUT ) { //<EFBFBD><EFBFBD><EFBFBD>Է<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʒ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>˹ر<EFBFBD>
|
||||
if ( !bOk && dwIOError != WAIT_TIMEOUT ) { //当对方的套机制发生了关闭
|
||||
if (ContextObject && This->m_bTimeToKill == FALSE &&dwTrans==0) {
|
||||
ContextObject->olps = NULL;
|
||||
Mprintf("!!! RemoveStaleContext: %d \n", WSAGetLastError());
|
||||
@@ -316,7 +316,7 @@ DWORD IOCPServer::WorkThreadProc(LPVOID lParam)
|
||||
continue;
|
||||
}
|
||||
if (!bError) {
|
||||
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD><EFBFBD>̵߳<EFBFBD><EFBFBD>̵߳<EFBFBD><EFBFBD>̳߳<EFBFBD>
|
||||
//分配一个新的线程到线程到线程池
|
||||
if (ulBusyThread == This->m_ulCurrentThread) {
|
||||
if (ulBusyThread < This->m_ulThreadPoolMax) {
|
||||
if (ContextObject != NULL) {
|
||||
@@ -376,7 +376,7 @@ DWORD IOCPServer::WorkThreadProc(LPVOID lParam)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//<EFBFBD>ڹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><EFBFBD>б<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//在工作线程中被调用
|
||||
BOOL IOCPServer::HandleIO(IOType PacketFlags,PCONTEXT_OBJECT ContextObject, DWORD dwTrans, ZSTD_DCtx* ctx)
|
||||
{
|
||||
BOOL bRet = FALSE;
|
||||
@@ -410,15 +410,15 @@ BOOL IOCPServer::OnClientInitializing(PCONTEXT_OBJECT ContextObject, DWORD dwTr
|
||||
// May be this function should be a member of `CONTEXT_OBJECT`.
|
||||
BOOL ParseReceivedData(CONTEXT_OBJECT * ContextObject, DWORD dwTrans, pfnNotifyProc m_NotifyProc, ZSTD_DCtx* m_Dctx)
|
||||
{
|
||||
AUTO_TICK(40);
|
||||
AUTO_TICK(40, "");
|
||||
BOOL ret = 1;
|
||||
try {
|
||||
if (dwTrans == 0) { //<EFBFBD>Է<EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
if (dwTrans == 0) { //对方关闭了套接字
|
||||
return FALSE;
|
||||
}
|
||||
//<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>wsabuff 8192
|
||||
//将接收到的数据拷贝到我们自己的内存中wsabuff 8192
|
||||
ContextObject->InCompressedBuffer.WriteBuffer((PBYTE)ContextObject->szBuffer,dwTrans);
|
||||
//<EFBFBD>鿴<EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//查看数据包的完整性
|
||||
while (true) {
|
||||
PR pr = ContextObject->Parse(ContextObject->InCompressedBuffer);
|
||||
if (pr.IsFailed()) {
|
||||
@@ -434,20 +434,20 @@ BOOL ParseReceivedData(CONTEXT_OBJECT * ContextObject, DWORD dwTrans, pfnNotifyP
|
||||
ContextObject->InDeCompressedBuffer.WriteBuffer(CompressedBuffer, ulCompressedLength);
|
||||
if (m_NotifyProc(ContextObject))
|
||||
ret = CompressedBuffer[0] == TOKEN_LOGIN ? 999 : 1;
|
||||
SAFE_DELETE_ARRAY(CompressedBuffer);
|
||||
// CompressedBuffer 由 CONTEXT_OBJECT 管理,不在此处释放
|
||||
break;
|
||||
}
|
||||
|
||||
ULONG ulPackTotalLength = 0;
|
||||
ContextObject->InCompressedBuffer.CopyBuffer(&ulPackTotalLength, sizeof(ULONG), pr.Result);
|
||||
//ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܳ<EFBFBD><EFBFBD><EFBFBD>5<EFBFBD>ֽڱ<EFBFBD>ʶ+4<>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0>ܳ<EFBFBD><DCB3><EFBFBD>+4<>ֽ<EFBFBD>ԭʼ<D4AD><CABC><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
|
||||
//取出数据包的总长度5字节标识+4字节数据包总长度+4字节原始数据长度
|
||||
int bufLen = ContextObject->InCompressedBuffer.GetBufferLength();
|
||||
if (ulPackTotalLength && bufLen >= ulPackTotalLength) {
|
||||
ULONG ulCompressedLength = 0;
|
||||
ULONG ulOriginalLength = 0;
|
||||
PBYTE CompressedBuffer = ContextObject->ReadBuffer(ulCompressedLength, ulOriginalLength);
|
||||
if (ContextObject->CompressMethod == COMPRESS_UNKNOWN) {
|
||||
delete[] CompressedBuffer;
|
||||
// CompressedBuffer 由 CONTEXT_OBJECT 管理,不在此处释放
|
||||
throw "Unknown method";
|
||||
} else if (ContextObject->CompressMethod == COMPRESS_NONE) {
|
||||
ContextObject->InDeCompressedBuffer.ClearBuffer();
|
||||
@@ -455,11 +455,12 @@ BOOL ParseReceivedData(CONTEXT_OBJECT * ContextObject, DWORD dwTrans, pfnNotifyP
|
||||
ContextObject->InDeCompressedBuffer.WriteBuffer(CompressedBuffer, ulOriginalLength);
|
||||
if (m_NotifyProc(ContextObject))
|
||||
ret = CompressedBuffer[0] == TOKEN_LOGIN ? 999 : 1;
|
||||
SAFE_DELETE_ARRAY(CompressedBuffer);
|
||||
// CompressedBuffer 由 CONTEXT_OBJECT 管理,不在此处释放
|
||||
continue;
|
||||
}
|
||||
bool usingZstd = ContextObject->CompressMethod == COMPRESS_ZSTD, zlibFailed = false;
|
||||
PBYTE DeCompressedBuffer = new BYTE[ulOriginalLength]; //<2F><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
|
||||
// 使用预分配缓冲区,避免频繁内存分配
|
||||
PBYTE DeCompressedBuffer = ContextObject->GetDecompressBuffer(ulOriginalLength);
|
||||
size_t iRet = usingZstd ?
|
||||
Muncompress(DeCompressedBuffer, &ulOriginalLength, CompressedBuffer, ulCompressedLength) :
|
||||
uncompress(DeCompressedBuffer, &ulOriginalLength, CompressedBuffer, ulCompressedLength);
|
||||
@@ -470,7 +471,7 @@ BOOL ParseReceivedData(CONTEXT_OBJECT * ContextObject, DWORD dwTrans, pfnNotifyP
|
||||
if (m_NotifyProc(ContextObject))
|
||||
ret = DeCompressedBuffer[0] == TOKEN_LOGIN ? 999 : 1;
|
||||
} else if (usingZstd) {
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>zlib<EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD>
|
||||
// 尝试用zlib解压缩
|
||||
if (Z_OK == uncompress(DeCompressedBuffer, &ulOriginalLength, CompressedBuffer, ulCompressedLength)) {
|
||||
ContextObject->CompressMethod = COMPRESS_ZLIB;
|
||||
ContextObject->InDeCompressedBuffer.ClearBuffer();
|
||||
@@ -485,8 +486,7 @@ BOOL ParseReceivedData(CONTEXT_OBJECT * ContextObject, DWORD dwTrans, pfnNotifyP
|
||||
} else {
|
||||
zlibFailed = true;
|
||||
}
|
||||
delete [] CompressedBuffer;
|
||||
delete [] DeCompressedBuffer;
|
||||
// CompressedBuffer 和 DeCompressedBuffer 都由 CONTEXT_OBJECT 管理,不在此处释放
|
||||
if (zlibFailed) {
|
||||
Mprintf("[ERROR] ZLIB uncompress failed \n");
|
||||
throw "Bad Buffer";
|
||||
@@ -510,7 +510,7 @@ BOOL IOCPServer::OnClientReceiving(PCONTEXT_OBJECT ContextObject, DWORD dwTrans
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PostRecv(ContextObject); //Ͷ<EFBFBD><EFBFBD><EFBFBD>µĽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
PostRecv(ContextObject); //投递新的接收数据的请求
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -518,7 +518,7 @@ BOOL IOCPServer::OnClientReceiving(PCONTEXT_OBJECT ContextObject, DWORD dwTrans
|
||||
BOOL WriteContextData(CONTEXT_OBJECT* ContextObject, PBYTE szBuffer, size_t ulOriginalLength, ZSTD_CCtx* m_Cctx)
|
||||
{
|
||||
assert(ContextObject);
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// 输出服务端所发送的命令
|
||||
int cmd = szBuffer[0];
|
||||
if (ulOriginalLength < 100 && cmd != COMMAND_SCREEN_CONTROL && cmd != CMD_HEARTBEAT_ACK &&
|
||||
cmd != CMD_DRAW_POINT && cmd != CMD_MOVEWINDOW && cmd != CMD_SET_SIZE) {
|
||||
@@ -544,9 +544,9 @@ BOOL WriteContextData(CONTEXT_OBJECT* ContextObject, PBYTE szBuffer, size_t ulOr
|
||||
}
|
||||
bool usingZstd = ContextObject->CompressMethod == COMPRESS_ZSTD;
|
||||
unsigned long ulCompressedLength = usingZstd ?
|
||||
ZSTD_compressBound(ulOriginalLength) : (double)ulOriginalLength * 1.001 + 12;
|
||||
BYTE buf[1024];
|
||||
LPBYTE CompressedBuffer = ulCompressedLength>1024 ? new BYTE[ulCompressedLength]:buf;
|
||||
ZSTD_compressBound(ulOriginalLength) : (unsigned long)((double)ulOriginalLength * 1.001 + 12);
|
||||
// 使用预分配缓冲区替代每次 new
|
||||
LPBYTE CompressedBuffer = ContextObject->GetSendCompressBuffer(ulCompressedLength);
|
||||
Buffer tmp(szBuffer, ulOriginalLength);
|
||||
szBuffer = tmp.Buf();
|
||||
ContextObject->Encode(szBuffer, ulOriginalLength);
|
||||
@@ -557,14 +557,14 @@ BOOL WriteContextData(CONTEXT_OBJECT* ContextObject, PBYTE szBuffer, size_t ulOr
|
||||
|
||||
if (usingZstd ? C_FAILED(iRet) : (S_OK != iRet)) {
|
||||
Mprintf("[ERROR] compress failed \n");
|
||||
if (CompressedBuffer != buf) delete [] CompressedBuffer;
|
||||
// SendCompressBuffer 由 CONTEXT_OBJECT 管理,不在此处释放
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ulCompressedLength = usingZstd ? iRet : ulCompressedLength;
|
||||
|
||||
ContextObject->WriteBuffer(CompressedBuffer, ulCompressedLength, ulOriginalLength, cmd);
|
||||
if (CompressedBuffer != buf) delete [] CompressedBuffer;
|
||||
// SendCompressBuffer 由 CONTEXT_OBJECT 管理,不在此处释放
|
||||
} while (false);
|
||||
|
||||
return TRUE;
|
||||
@@ -579,9 +579,9 @@ BOOL IOCPServer::OnClientPreSending(CONTEXT_OBJECT* ContextObject, PBYTE szBuffe
|
||||
if (WriteContextData(ContextObject, szBuffer, ulOriginalLength)) {
|
||||
OVERLAPPEDPLUS* OverlappedPlus = new OVERLAPPEDPLUS(IOWrite);
|
||||
BOOL bOk = PostQueuedCompletionStatus(m_hCompletionPort, 0, (ULONG_PTR)ContextObject, &OverlappedPlus->m_ol);
|
||||
if ( (!bOk && GetLastError() != ERROR_IO_PENDING) ) { //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͷ<EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>
|
||||
if ( (!bOk && GetLastError() != ERROR_IO_PENDING) ) { //如果投递失败
|
||||
int a = GetLastError();
|
||||
Mprintf("!!! OnClientPreSending Ͷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣʧ<EFBFBD><EFBFBD>\n");
|
||||
Mprintf("!!! OnClientPreSending 投递消息失败\n");
|
||||
RemoveStaleContext(ContextObject);
|
||||
SAFE_DELETE(OverlappedPlus);
|
||||
return FALSE;
|
||||
@@ -597,12 +597,12 @@ BOOL IOCPServer::OnClientPostSending(CONTEXT_OBJECT* ContextObject,ULONG ulCompl
|
||||
try {
|
||||
DWORD ulFlags = MSG_PARTIAL;
|
||||
|
||||
ContextObject->OutCompressedBuffer.RemoveCompletedBuffer(ulCompletedLength); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݽṹ<EFBFBD><EFBFBD>ȥ<EFBFBD><EFBFBD>
|
||||
ContextObject->OutCompressedBuffer.RemoveCompletedBuffer(ulCompletedLength); //将完成的数据从数据结构中去除
|
||||
if (ContextObject->OutCompressedBuffer.GetBufferLength() == 0) {
|
||||
ContextObject->OutCompressedBuffer.ClearBuffer();
|
||||
return true; //<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>
|
||||
return true; //走到这里说明我们的数据真正完全发送
|
||||
} else {
|
||||
OVERLAPPEDPLUS * OverlappedPlus = new OVERLAPPEDPLUS(IOWrite); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>Ǽ<EFBFBD><C7BC><EFBFBD>Ͷ<EFBFBD><CDB6> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
OVERLAPPEDPLUS * OverlappedPlus = new OVERLAPPEDPLUS(IOWrite); //数据没有完成 我们继续投递 发送请求
|
||||
|
||||
ContextObject->wsaOutBuffer.buf = (char*)ContextObject->OutCompressedBuffer.GetBuffer(0);
|
||||
ContextObject->wsaOutBuffer.len = ContextObject->OutCompressedBuffer.GetBufferLength();
|
||||
@@ -610,7 +610,7 @@ BOOL IOCPServer::OnClientPostSending(CONTEXT_OBJECT* ContextObject,ULONG ulCompl
|
||||
NULL, ulFlags,&OverlappedPlus->m_ol, NULL);
|
||||
if ( iOk == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING ) {
|
||||
int a = GetLastError();
|
||||
Mprintf("!!! OnClientPostSending Ͷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣʧ<EFBFBD><EFBFBD>: %d\n", a);
|
||||
Mprintf("!!! OnClientPostSending 投递消息失败: %d\n", a);
|
||||
RemoveStaleContext(ContextObject);
|
||||
SAFE_DELETE(OverlappedPlus);
|
||||
return FALSE;
|
||||
@@ -624,7 +624,7 @@ BOOL IOCPServer::OnClientPostSending(CONTEXT_OBJECT* ContextObject,ULONG ulCompl
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD IOCPServer::ListenThreadProc(LPVOID lParam) //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
|
||||
DWORD IOCPServer::ListenThreadProc(LPVOID lParam) //监听线程
|
||||
{
|
||||
IOCPServer* This = (IOCPServer*)(lParam);
|
||||
WSANETWORKEVENTS NetWorkEvents;
|
||||
@@ -639,7 +639,7 @@ DWORD IOCPServer::ListenThreadProc(LPVOID lParam) //
|
||||
continue;
|
||||
|
||||
int iRet = WSAEnumNetworkEvents(This->m_sListenSocket,
|
||||
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>Ǿͽ<C7BE><CDBD><EFBFBD><EFBFBD>¼<EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ж<EFBFBD>
|
||||
//如果事件授信 我们就将该事件转换成一个网络事件 进行 判断
|
||||
This->m_hListenEvent,
|
||||
&NetWorkEvents);
|
||||
|
||||
@@ -666,12 +666,12 @@ void IOCPServer::OnAccept()
|
||||
int iLen = sizeof(SOCKADDR_IN);
|
||||
sClientSocket = accept(m_sListenSocket,
|
||||
(sockaddr*)&ClientAddr,
|
||||
&iLen); //ͨ<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><EFBFBD><EFBFBD>
|
||||
&iLen); //通过我们的监听套接字来生成一个与之信号通信的套接字
|
||||
if (sClientSocket == SOCKET_ERROR) {
|
||||
return;
|
||||
}
|
||||
|
||||
//<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>֮<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><EFBFBD>
|
||||
//我们在这里为每一个到达的信号维护了一个与之关联的数据结构这里简称为用户的上下背景文
|
||||
PCONTEXT_OBJECT ContextObject = AllocateContext(sClientSocket); // Context
|
||||
|
||||
if (ContextObject == NULL) {
|
||||
@@ -699,34 +699,34 @@ void IOCPServer::OnAccept()
|
||||
return;
|
||||
}
|
||||
|
||||
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD>ѡ<EFBFBD> Set KeepAlive <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> SO_KEEPALIVE
|
||||
//<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>2Сʱ<EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD>ӿڵ<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û
|
||||
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>TCP<EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Է<EFBFBD> <20><>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD>
|
||||
//设置套接字的选项卡 Set KeepAlive 开启保活机制 SO_KEEPALIVE
|
||||
//保持连接检测对方主机是否崩溃如果2小时内在此套接口的任一方向都没
|
||||
//有数据交换,TCP就自动给对方 发一个保持存活
|
||||
m_ulKeepLiveTime = 3;
|
||||
const BOOL bKeepAlive = TRUE;
|
||||
setsockopt(ContextObject->sClientSocket,SOL_SOCKET,SO_KEEPALIVE,(char*)&bKeepAlive,sizeof(bKeepAlive));
|
||||
|
||||
//<EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD>ʱ<EFBFBD><EFBFBD>ϸ<EFBFBD><EFBFBD>Ϣ
|
||||
//设置超时详细信息
|
||||
tcp_keepalive KeepAlive;
|
||||
KeepAlive.onoff = 1; // <EFBFBD><EFBFBD><EFBFBD>ñ<EFBFBD><EFBFBD><EFBFBD>
|
||||
KeepAlive.keepalivetime = m_ulKeepLiveTime; //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>3<EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><EFBFBD>ͷ<EFBFBD><EFBFBD><EFBFBD>̽<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
KeepAlive.keepaliveinterval = 1000 * 10; //<EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><EFBFBD><EFBFBD>Ϊ10<EFBFBD><EFBFBD> Resend if No-Reply
|
||||
KeepAlive.onoff = 1; // 启用保活
|
||||
KeepAlive.keepalivetime = m_ulKeepLiveTime; //超过3分钟没有数据,就发送探测包
|
||||
KeepAlive.keepaliveinterval = 1000 * 10; //重试间隔为10秒 Resend if No-Reply
|
||||
WSAIoctl(ContextObject->sClientSocket, SIO_KEEPALIVE_VALS,&KeepAlive,sizeof(KeepAlive),
|
||||
NULL,0,(unsigned long *)&bKeepAlive,0,NULL);
|
||||
|
||||
//<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><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>û<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SO_KEEPALIVEѡ<EFBFBD>
|
||||
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һֱ<EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD>SOCKET<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><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
||||
//在做服务器时,如果发生客户端网线或断电等非正常断开的现象,如果服务器没有设置SO_KEEPALIVE选项,
|
||||
//则会一直不关闭SOCKET。因为上的的设置是默认两个小时时间太长了所以我们就修正这个值
|
||||
EnterCriticalSection(&m_cs);
|
||||
m_ContextConnectionList.AddTail(ContextObject); //<EFBFBD><EFBFBD><EFBFBD>뵽<EFBFBD><EFBFBD><EFBFBD>ǵ<EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD>б<EFBFBD><EFBFBD><EFBFBD>
|
||||
m_ContextConnectionList.AddTail(ContextObject); //插入到我们的内存列表中
|
||||
LeaveCriticalSection(&m_cs);
|
||||
|
||||
OVERLAPPEDPLUS *OverlappedPlus = new OVERLAPPEDPLUS(IOInitialize); //ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>IO<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
OVERLAPPEDPLUS *OverlappedPlus = new OVERLAPPEDPLUS(IOInitialize); //注意这里的重叠IO请求是 用户请求上线
|
||||
|
||||
BOOL bOk = PostQueuedCompletionStatus(m_hCompletionPort, 0, (ULONG_PTR)ContextObject, &OverlappedPlus->m_ol); // <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><EFBFBD><EFBFBD>ô<EFBFBD><EFBFBD><EFBFBD>Ǿͽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɶ˿<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ǵĹ<C7B5><C4B9><EFBFBD><EFBFBD>̴߳<DFB3><CCB4><EFBFBD><EFBFBD><EFBFBD>
|
||||
if ( (!bOk && GetLastError() != ERROR_IO_PENDING)) { //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͷ<EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>
|
||||
BOOL bOk = PostQueuedCompletionStatus(m_hCompletionPort, 0, (ULONG_PTR)ContextObject, &OverlappedPlus->m_ol); // 工作线程
|
||||
//因为我们接受到了一个用户上线的请求那么我们就将该请求发送给我们的完成端口 让我们的工作线程处理它
|
||||
if ( (!bOk && GetLastError() != ERROR_IO_PENDING)) { //如果投递失败
|
||||
int a = GetLastError();
|
||||
Mprintf("!!! OnAccept Ͷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣʧ<EFBFBD><EFBFBD>\n");
|
||||
Mprintf("!!! OnAccept 投递消息失败\n");
|
||||
RemoveStaleContext(ContextObject);
|
||||
SAFE_DELETE(OverlappedPlus);
|
||||
return;
|
||||
@@ -737,9 +737,9 @@ void IOCPServer::OnAccept()
|
||||
|
||||
VOID IOCPServer::PostRecv(CONTEXT_OBJECT* ContextObject)
|
||||
{
|
||||
//<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><EFBFBD><EFBFBD>
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD>ĵ<EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD>;<EFBFBD><EFBFBD>DZ<EFBFBD><EFBFBD>ض˵ĵ<EFBFBD>½<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǵĹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳̾<EFBFBD>
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ProcessIOMessage<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//向我们的刚上线的用户的投递一个接受数据的请求
|
||||
// 如果用户的第一个数据包到达也就就是被控端的登陆请求到达我们的工作线程就
|
||||
// 会响应,并调用ProcessIOMessage函数
|
||||
OVERLAPPEDPLUS * OverlappedPlus = new OVERLAPPEDPLUS(IORead);
|
||||
ContextObject->olps = OverlappedPlus;
|
||||
|
||||
@@ -750,7 +750,7 @@ VOID IOCPServer::PostRecv(CONTEXT_OBJECT* ContextObject)
|
||||
|
||||
if (iOk == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING) {
|
||||
int a = GetLastError();
|
||||
Mprintf("!!! PostRecv Ͷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣʧ<EFBFBD><EFBFBD>\n");
|
||||
Mprintf("!!! PostRecv 投递消息失败\n");
|
||||
RemoveStaleContext(ContextObject);
|
||||
SAFE_DELETE(OverlappedPlus);
|
||||
}
|
||||
@@ -780,18 +780,18 @@ VOID IOCPServer::RemoveStaleContext(CONTEXT_OBJECT* ContextObject)
|
||||
EnterCriticalSection(&m_cs);
|
||||
auto find = m_ContextConnectionList.Find(ContextObject);
|
||||
LeaveCriticalSection(&m_cs);
|
||||
if (find) { //<EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD>в<EFBFBD><EFBFBD>Ҹ<EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݽṹ
|
||||
if (find) { //在内存中查找该用户的上下文数据结构
|
||||
m_OfflineProc(ContextObject);
|
||||
|
||||
CancelIo((HANDLE)ContextObject->sClientSocket); //ȡ<EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD>첽IO -->PostRecv
|
||||
closesocket(ContextObject->sClientSocket); //<EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
CancelIo((HANDLE)ContextObject->sClientSocket); //取消在当前套接字的异步IO -->PostRecv
|
||||
closesocket(ContextObject->sClientSocket); //关闭套接字
|
||||
ContextObject->sClientSocket = INVALID_SOCKET;
|
||||
|
||||
while (!HasOverlappedIoCompleted((LPOVERLAPPED)ContextObject)) { //<EFBFBD>жϻ<EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD>첽IO<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
while (!HasOverlappedIoCompleted((LPOVERLAPPED)ContextObject)) { //判断还有没有异步IO请求在当前套接字上
|
||||
Sleep(0);
|
||||
}
|
||||
|
||||
MoveContextToFreePoolList(ContextObject); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD>ṹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD>
|
||||
MoveContextToFreePoolList(ContextObject); //将该内存结构回收至内存池
|
||||
}
|
||||
}
|
||||
|
||||
@@ -806,8 +806,8 @@ VOID IOCPServer::MoveContextToFreePoolList(CONTEXT_OBJECT* ContextObject)
|
||||
ContextObject->OutCompressedBuffer.ClearBuffer();
|
||||
|
||||
memset(ContextObject->szBuffer,0,8192);
|
||||
m_ContextFreePoolList.AddTail(ContextObject); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD>
|
||||
m_ContextConnectionList.RemoveAt(Pos); //<EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD>ṹ<EFBFBD><EFBFBD><EFBFBD>Ƴ<EFBFBD>
|
||||
m_ContextFreePoolList.AddTail(ContextObject); //回收至内存池
|
||||
m_ContextConnectionList.RemoveAt(Pos); //从内存结构中移除
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user