memset 、ZeroMemory和 “={0}” 三者区别

本文详细解释了ZeroMemory和memset两个函数的区别,并对比了它们与初始化语法“={0}

memset是以字节为单位,初始化内存块。
当初始化一个字节单位的数组时,可以用memset把每个数组单元初始化成任何你想要的值,比如
char data[10];  
memset(data, 1, sizeof(data));    // right  
memset(data, 0, sizeof(data));    // right 

而在初始化其他基础类型时,则需要注意,比如,
int data[10];  
memset(data, 0, sizeof(data));    // right  
memset(data, -1, sizeof(data));    // right  
memset(data, 1, sizeof(data));    // wrong, data[x] would be 0x0101 instead of 1

以上内容引用自:http://blog.youkuaiyun.com/my_business/article/details/40537653#

ZeroMemorymemset 和 “={0}” 三者区别:

首先是ZeroMemorymemset的区别:

1、ZeroMemory是微软的SDK提供的,memset属于C Run-time Library提供的。
因此ZeroMemory只能用于Windows系统,而memset还可用于其他系统。


2、ZeroMemory是一个宏,只是用于把一段内存的内容置零,内部其实是用 
memset实现的,而memset除了对内存进行清零操作,还可以将内存置成别的字符。


3、如果程序是Win32程序而且不想连接c运行时库,那就用ZeroMemory,如果需要跨平台,那就用memset

所以如果ZeroMemorymemset用于清零操作,其本质是一样的。

然后说说ZeroMemory和 “={0}”的区别:

1、ZeroMemory会将结构中所有字节置0,而“={0}”只会将成员置0,其中填充字节不变。

2、一个struct有构造函数或虚函数时,ZeroMemory可以编译通过,而“={0}”会产生编译错误。其中,“={0}”的编译错误起到了一定的保护作用,
因为对一个有虚函数的对象使用ZeroMemory时,会将其虚函数的指针置0,这是非常危险的(调用虚函数时,空指针很可能引起程序崩溃)。


/*----------------------------------------------------------------------- 第13章 Hook技术 《加密与解密(第四版)》 (c) 看雪学院 www.kanxue.com 2000-2018 -----------------------------------------------------------------------*/ // VEHHook.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <windows.h> BOOL SetBreakPoint(PVOID pFuncAddr); BOOL ClearBreakPoint(PVOID pFuncAddr); BOOL InstallVEHHook(PVECTORED_EXCEPTION_HANDLER Handler); VOID UnInstallVEHHook(); typedef int (WINAPI *PFN_MessageBox)( HWND hWnd, // handle of owner window LPCTSTR lpText, // address of text in message box LPCTSTR lpCaption, // address of title of message box UINT uType // style of message box ); int WINAPI My_MessageBox( HWND hWnd, // handle of owner window LPCTSTR lpText, // address of text in message box LPCTSTR lpCaption, // address of title of message box UINT uType // style of message box ); LONG WINAPI VectoredHandler1(struct _EXCEPTION_POINTERS *ExceptionInfo); LONG WINAPI VectoredHandler2(struct _EXCEPTION_POINTERS *ExceptionInfo); LONG WINAPI VectoredHandler3(struct _EXCEPTION_POINTERS *ExceptionInfo); VOID ShowMsgBox(LPCTSTR lpMsg); ULONG_PTR InitTrampolineFun(); PFN_MessageBox g_OriginalMessageBoxA; PVOID g_AddrofMessageBoxA = 0 ; PVOID g_hVector; BYTE g_OldCode[16]={0}; int main(int argc, char* argv[]) { HMODULE hUser32 = LoadLibrary("user32.dll"); g_AddrofMessageBoxA = (PVOID)GetProcAddress(hUser32,"MessageBoxA"); printf("Address of MessageBoxA = 0x%p\n",g_AddrofMessageBoxA); g_OriginalMessageBoxA = (PFN_MessageBox)InitTrampolineFun(); //跳过开头的Hook printf("Addr of VectoredHandler1 = 0x%p\n",VectoredHandler1); printf("Addr of VectoredHandler2 = 0x%p\n",VectoredHandler2); printf("Addr of VectoredHandler3 = 0x%p\n",VectoredHandler3); //选择安装一个进行测试 InstallVEHHook(VectoredHandler1); //设置断点 SetBreakPoint(g_AddrofMessageBoxA); //call ShowMsgBox("VEH Hook Test."); printf("All Finished!\n"); ClearBreakPoint(g_AddrofMessageBoxA); UnInstallVEHHook(); ShowMsgBox("Hook Cleared"); return 0; } VOID ShowMsgBox(LPCTSTR lpMsg) { MessageBoxA(NULL,lpMsg,"Test",MB_OK); } ULONG_PTR InitTrampolineFun() { ULONG_PTR uResult = 0 ; PBYTE pFun = NULL; #ifdef _WIN64 //x64需要申请shellcode /* USER32!MessageBoxA: 00000000`779412b8 4883ec38 sub rsp,38h 00000000`779412bc 4533db xor r11d,r11d 00000000`779412bf 44391d760e0200 cmp dword ptr [USER32!gapfnScSendMessage+0x927c (00000000`7796213c)],r11d */ pFun = (PBYTE)VirtualAlloc(NULL,128,MEM_COMMIT,PAGE_EXECUTE_READWRITE); uResult = (ULONG_PTR)pFun; memset(pFun,0,128); memcpy(pFun,(PVOID)g_AddrofMessageBoxA,4); //拷贝第一条指令,4字节,推荐使用反汇编引擎来实际计算 pFun += 4 ; //下一条指令构造为jmp [xxxxxx] pFun[0] = 0xFF; pFun[1] = 0x25; *(ULONG_PTR*)(pFun + 6) = (ULONG_PTR)g_AddrofMessageBoxA + 4 ; //跳回到原函数加4的地方 #else //x86,第一条指令是mov edi,edi,直接跳过即可 uResult = (ULONG_PTR)g_AddrofMessageBoxA + 2; #endif return uResult; } //处理方式,修改参数并返回原函数继续执行 LONG WINAPI VectoredHandler1( struct _EXCEPTION_POINTERS *ExceptionInfo ) { char *szNewMsg = "[VectoredHandler1] Hacked by pediy.com"; LONG lResult = EXCEPTION_CONTINUE_SEARCH ; PEXCEPTION_RECORD pExceptionRecord; PCONTEXT pContextRecord; int ret = 0 ; pExceptionRecord = ExceptionInfo->ExceptionRecord ; pContextRecord = ExceptionInfo->ContextRecord ; ULONG_PTR* uESP = 0 ; printf("Exception Address = %p\n",pExceptionRecord->ExceptionAddress); if (pExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT && pExceptionRecord->ExceptionAddress == g_AddrofMessageBoxA) { #ifdef _WIN64 //x64上前四个参数依次为RCX,RDX,R8,R9 //修改第二个参数,即LpMsg printf("lpText = 0x%p %s\n",pContextRecord->Rdx,(char*)pContextRecord->Rdx); pContextRecord->Rdx = (ULONG_PTR)szNewMsg; pContextRecord->Rip = (ULONG_PTR)g_OriginalMessageBoxA ; //跳到Trampoline继续执行 #else /* 0012FF70 0040105A /CALL 到 MessageBoxA 来自 VEHHook.00401054 0012FF74 00000000 |hOwner = NULL 0012FF78 00407030 |Text = "VEH Hook" 0012FF7C 0040703C |Title = "Test" 0012FF80 00000000 \Style = MB_OK|MB_APPLMODAL 0012FF84 00401225 返回到 VEHHook.<ModuleEntryPoint>+0B4 来自 VEHHook.00401000 */ printf("ESP = 0x%p\n",pContextRecord->Esp) ; uESP = (ULONG_PTR*)pContextRecord->Esp ; //取中断时的ESP uESP[2] = (ULONG_PTR)szNewMsg; //修改栈中的参数 pContextRecord->Eip = (ULONG_PTR)g_OriginalMessageBoxA ; //跳过函数开头 #endif lResult = EXCEPTION_CONTINUE_EXECUTION ; } return lResult; } //处理方式:直接调用原函数并替原函数返回 LONG WINAPI VectoredHandler2( struct _EXCEPTION_POINTERS *ExceptionInfo ) { char *szNewMsg = "[VectoredHandler2] Hacked by pediy.com"; LONG lResult = EXCEPTION_CONTINUE_SEARCH ; PEXCEPTION_RECORD pExceptionRecord; PCONTEXT pContextRecord; int ret = 0 ; pExceptionRecord = ExceptionInfo->ExceptionRecord ; pContextRecord = ExceptionInfo->ContextRecord ; ULONG_PTR* uESP = 0 ; if (pExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT && pExceptionRecord->ExceptionAddress == g_AddrofMessageBoxA) { #ifdef _WIN64 //x64上前四个参数依次为RCX,RDX,R8,R9 printf("RSP = 0x%p\n",pContextRecord->Rsp) ; uESP = (ULONG_PTR*)pContextRecord->Rsp ; printf("Return Address = 0x%p\n",uESP[0]); ret = g_OriginalMessageBoxA((HWND)pContextRecord->Rcx,szNewMsg,(LPCTSTR)pContextRecord->R8,(int)pContextRecord->R9); printf("ret = %d\n",ret); //修正RSP pContextRecord->Rsp += sizeof(ULONG_PTR);//参数在寄存器中,栈中无参数,仅需跳过返回地址 //直接返回到调用者处 pContextRecord->Rip = uESP[0] ;//设置EIP为返回地址 #else /* 0012FF70 0040105A /CALL 到 MessageBoxA 来自 VEHHook.00401054 0012FF74 00000000 |hOwner = NULL 0012FF78 00407030 |Text = "VEH Hook" 0012FF7C 0040703C |Title = "Test" 0012FF80 00000000 \Style = MB_OK|MB_APPLMODAL 0012FF84 00401225 返回到 VEHHook.<ModuleEntryPoint>+0B4 来自 VEHHook.00401000 */ printf("ESP = 0x%p\n",pContextRecord->Esp) ; uESP = (ULONG_PTR*)pContextRecord->Esp ; ret = g_OriginalMessageBoxA((HWND)uESP[1],szNewMsg,(LPCTSTR)uESP[3],(int)uESP[4]); printf("ret = %d\n",ret); //直接返回到调用者处 pContextRecord->Eip = uESP[0] ;//设置EIP为返回地址 pContextRecord->Esp += (4 + 1)*sizeof(ULONG_PTR); //4为参数个数,1为返回地址 #endif lResult = EXCEPTION_CONTINUE_EXECUTION ; } return lResult; } //处理方式:直接返回,相当于过滤掉 LONG WINAPI VectoredHandler3( struct _EXCEPTION_POINTERS *ExceptionInfo ) { LONG lResult = EXCEPTION_CONTINUE_SEARCH ; PEXCEPTION_RECORD pExceptionRecord = ExceptionInfo->ExceptionRecord ; PCONTEXT pContextRecord = ExceptionInfo->ContextRecord ; ULONG_PTR* uESP = 0 ; if (pExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT && pExceptionRecord->ExceptionAddress == g_AddrofMessageBoxA) { /* 0012FF70 0040105A /CALL 到 MessageBoxA 来自 VEHHook.00401054 0012FF74 00000000 |hOwner = NULL 0012FF78 00407030 |Text = "VEH Hook" 0012FF7C 0040703C |Title = "Test" 0012FF80 00000000 \Style = MB_OK|MB_APPLMODAL 0012FF84 00401225 返回到 VEHHook.<ModuleEntryPoint>+0B4 来自 VEHHook.00401000 */ //直接返回到调用者处 #ifdef _WIN64 printf("RSP = 0x%p\n",pContextRecord->Rsp) ; uESP = (ULONG_PTR*)pContextRecord->Rsp ; pContextRecord->Rip = uESP[0] ;//设置EIP为返回地址 pContextRecord->Rsp += sizeof(ULONG_PTR); //将压入栈内的参数返回地址清理掉,4为参数个数,1为返回地址 #else printf("ESP = 0x%X\n",pContextRecord->Esp) ; uESP = (ULONG_PTR*)pContextRecord->Esp ; pContextRecord->Eip = uESP[0] ;//设置EIP为返回地址 pContextRecord->Esp += (4 + 1)*sizeof(ULONG_PTR); //将压入栈内的参数返回地址清理掉,4为参数个数,1为返回地址 #endif lResult = EXCEPTION_CONTINUE_EXECUTION ; } return lResult; } BOOL InstallVEHHook(PVECTORED_EXCEPTION_HANDLER Handler) { printf("Current Handler Address = 0x%p\n",Handler); g_hVector = AddVectoredExceptionHandler(1,Handler); return g_hVector != NULL ; } VOID UnInstallVEHHook() { RemoveVectoredExceptionHandler(g_hVector); } /* 0:000> u user32!messageboxA USER32!MessageBoxA: 77d507ea 8bff mov edi,edi 77d507ec 55 push ebp 77d507ed 8bec mov ebp,esp */ BOOL SetBreakPoint(PVOID pFuncAddr) { DWORD dwCnt = 0 ; BYTE *pTarget = (BYTE*)pFuncAddr; g_OldCode[0] = *pTarget; printf("Original Fun Head Code = 0x%02X\n",g_OldCode[0]); //修改内存页的属性 DWORD dwOLD; MEMORY_BASIC_INFORMATION mbi; VirtualQuery(pTarget,&mbi,sizeof(mbi)); VirtualProtect(mbi.BaseAddress,mbi.RegionSize,PAGE_EXECUTE_READWRITE,&dwOLD); //写入int3 *pTarget = 0xCC ; //恢复内存页的属性 VirtualProtect(mbi.BaseAddress,mbi.RegionSize,dwOLD,0); return TRUE; } BOOL ClearBreakPoint(PVOID pFuncAddr) { BYTE *pTarget = (BYTE*)pFuncAddr; //修改内存页的属性 DWORD dwOLD; MEMORY_BASIC_INFORMATION mbi; VirtualQuery(pTarget,&mbi,sizeof(mbi)); VirtualProtect(mbi.BaseAddress,mbi.RegionSize,PAGE_EXECUTE_READWRITE,&dwOLD); *pTarget = g_OldCode[0] ; //恢复内存页的属性 VirtualProtect(mbi.BaseAddress,mbi.RegionSize,dwOLD,0); return TRUE; } int WINAPI My_MessageBox( HWND hWnd, // handle of owner window LPCTSTR lpText, // address of text in message box LPCTSTR lpCaption, // address of title of message box UINT uType // style of message box ) { char newMsg[400]; char newCation[]="标题被我改了!"; int result; if (lpText) { ZeroMemory(newMsg,400); lstrcpy(newMsg,lpText); lstrcat(newMsg,"\n\tMessage Box hacked by pediy.com"); } printf("有人调用MessageBox...\n"); result = g_OriginalMessageBoxA(hWnd,newMsg,newCation,uType); return result; }分析是什么代码?有什么作用?如何执行
07-25
#define WIN32_LEAN_AND_MEAN #define _WINSOCK_DEPRECATED_NO_WARNINGS #include <winsock2.h> #include <windows.h> #include <iostream> #include <iomanip> #include <sstream> #include <string> #include <fstream> #include <unordered_map> #include <algorithm> #include <cstring> #include <atomic> #include <thread> #include <chrono> #include <vector> #include <queue> #include <mutex> #include <condition_variable> #pragma comment(lib, "ws2_32.lib") #pragma comment(lib, "mswsock.lib") // 用于AcceptEx等异步操作 using namespace std; // 常量定义 constexpr DWORD CLIENT_SUB_ADDRESS = 0xAED9F0; constexpr DWORD CRAG_CONNECTION_INSTANCE_R_ADDRESS = 0xAEDE00; constexpr DWORD RECV_PTR_ADDRESS = 0x1424E18; constexpr int RING_BUFFER_SIZE = 64 * 1024; // 64KB环形缓冲区 constexpr int PACKET_POOL_SIZE = 1024; // 预分配1024个封包对象 constexpr int MAX_PACKET_SIZE = 8192; // 最大封包大小8KB constexpr DWORD TIMEOUT = 600000; // 10分钟超时 constexpr DWORD RECONNECT_INTERVAL = 3000; // 3秒重连间隔 constexpr DWORD PING_INTERVAL = 5000; // 5秒Ping间隔 constexpr DWORD SLEEP_TIME = 5; // 5ms休眠 constexpr DWORD HOOK_DELAY = 3000; // 3秒延迟应用Hook constexpr int WORKER_THREAD_COUNT = 4; // 工作线程数量 constexpr int MAX_ASYNC_OPS = 100; // 最大异步操作数量 enum e_PacketType { RECEIVED = 0, SENDED = 1 }; // 原子类型定义 using atomic_socket = atomic<SOCKET>; using atomic_bool = atomic<bool>; using atomic_dword = atomic<DWORD>; // 前向声明 typedef int(__thiscall* SendToClientFunc)(void* CragConnection, size_t size, char* buffer); typedef void* (__stdcall* originalInstanceR)(void); // 异步操作上下文 struct AsyncOperationContext { OVERLAPPED overlapped; SOCKET socket; WSABUF wsaBuf; char buffer[MAX_PACKET_SIZE]; DWORD bytesTransferred; DWORD flags; atomic_bool inUse; AsyncOperationContext() : socket(INVALID_SOCKET), bytesTransferred(0), flags(0) { ZeroMemory(&overlapped, sizeof(OVERLAPPED)); ZeroMemory(buffer, MAX_PACKET_SIZE); inUse.store(false, memory_order_relaxed); } void reset() { ZeroMemory(&overlapped, sizeof(OVERLAPPED)); bytesTransferred = 0; flags = 0; inUse.store(false, memory_order_relaxed); } }; // 线程安全的队列 template<typename T> class ThreadSafeQueue { private: queue<T> queue_; mutable mutex mutex_; condition_variable cond_; public: void push(T value) { lock_guard<mutex> lock(mutex_); queue_.push(move(value)); cond_.notify_one(); } bool try_pop(T& value) { lock_guard<mutex> lock(mutex_); if (queue_.empty()) { return false; } value = move(queue_.front()); queue_.pop(); return true; } bool empty() const { lock_guard<mutex> lock(mutex_); return queue_.empty(); } size_t size() const { lock_guard<mutex> lock(mutex_); return queue_.size(); } }; // 极简环形缓冲区 class SimpleRingBuffer { private: char* buffer; atomic<uint32_t> read_pos; atomic<uint32_t> write_pos; uint32_t size_mask; public: SimpleRingBuffer(uint32_t size) { // 确保大小为2的幂 uint32_t actual_size = 1; while (actual_size < size) actual_size <<= 1; buffer = new char[actual_size]; size_mask = actual_size - 1; read_pos.store(0, memory_order_relaxed); write_pos.store(0, memory_order_relaxed); } ~SimpleRingBuffer() { delete[] buffer; } uint32_t available_read() const { return write_pos.load(memory_order_acquire) - read_pos.load(memory_order_acquire); } uint32_t available_write() const { return size_mask + 1 - (write_pos.load(memory_order_acquire) - read_pos.load(memory_order_acquire)); } bool push(const char* data, uint32_t len) { uint32_t wp = write_pos.load(memory_order_acquire); uint32_t rp = read_pos.load(memory_order_acquire); uint32_t available = size_mask + 1 - (wp - rp); if (available < len) return false; uint32_t index = wp & size_mask; uint32_t first_chunk = min(len, size_mask + 1 - index); memcpy(buffer + index, data, first_chunk); if (first_chunk < len) { memcpy(buffer, data + first_chunk, len - first_chunk); } write_pos.store(wp + len, memory_order_release); return true; } uint32_t pop(char* dest, uint32_t len) { uint32_t rp = read_pos.load(memory_order_acquire); uint32_t wp = write_pos.load(memory_order_acquire); uint32_t available = wp - rp; if (available == 0) return 0; uint32_t to_read = min(len, available); uint32_t index = rp & size_mask; uint32_t first_chunk = min(to_read, size_mask + 1 - index); memcpy(dest, buffer + index, first_chunk); if (first_chunk < to_read) { memcpy(dest + first_chunk, buffer, to_read - first_chunk); } read_pos.store(rp + to_read, memory_order_release); return to_read; } void clear() { read_pos.store(0, memory_order_relaxed); write_pos.store(0, memory_order_relaxed); } }; // 极简内存池 class SimplePacketPool { private: struct PacketNode { char data[MAX_PACKET_SIZE]; uint16_t size; atomic<PacketNode*> next; }; PacketNode* nodes; atomic<PacketNode*> free_head; public: SimplePacketPool(size_t count) { nodes = new PacketNode[count]; // 构建链表 for (size_t i = 0; i < count - 1; ++i) { nodes[i].next.store(&nodes[i + 1], memory_order_relaxed); } nodes[count - 1].next.store(nullptr, memory_order_relaxed); free_head.store(nodes, memory_order_relaxed); } ~SimplePacketPool() { delete[] nodes; } PacketNode* acquire() { PacketNode* current_head = free_head.load(memory_order_acquire); while (current_head) { if (free_head.compare_exchange_weak(current_head, current_head->next.load(memory_order_acquire), memory_order_acq_rel, memory_order_acquire)) { return current_head; } } return nullptr; } void release(PacketNode* node) { if (!node) return; PacketNode* current_head = free_head.load(memory_order_acquire); node->next.store(current_head, memory_order_relaxed); while (!free_head.compare_exchange_weak(current_head, node, memory_order_acq_rel, memory_order_acquire)) { node->next.store(current_head, memory_order_relaxed); } } }; // 全局变量 atomic_socket koreClient(INVALID_SOCKET); atomic_socket roServer(INVALID_SOCKET); atomic_bool koreClientIsAlive(false); atomic_bool keepMainThread(true); atomic_bool imalive(false); atomic_bool hook_applied(false); atomic_bool hook_delayed(false); SimpleRingBuffer sendBuffer(RING_BUFFER_SIZE); SimplePacketPool packetPool(PACKET_POOL_SIZE); string koreServerIP; DWORD koreServerPort; bool allowMultiClient = false; // Hook相关 typedef int (WINAPI* recv_func_t)(SOCKET s, char* buf, int len, int flags); recv_func_t original_recv = nullptr; // 异步I/O相关 HANDLE iocpHandle = NULL; vector<AsyncOperationContext*> asyncContexts; ThreadSafeQueue<AsyncOperationContext*> freeContexts; mutex contextMutex; // 工作线程池 vector<thread> workerThreads; atomic_bool workersRunning(false); // 函数声明 void AllocateConsole(); void debug(const char* msg); bool CreateDefaultConfig(const std::string& filename); bool LoadConfig(const std::string& filename); bool ApplyHook(); void RemoveHook(); bool isConnected(SOCKET s); SOCKET createSocket(const std::string& ip, int port); DWORD GetUserPort(); void init(); void finish(); // 异步I/O函数声明 bool InitializeAsyncIO(); void CleanupAsyncIO(); AsyncOperationContext* GetAsyncContext(); void ReturnAsyncContext(AsyncOperationContext* context); bool PostAsyncRecv(SOCKET socket); void WorkerThreadProc(); bool InitializeWorkerThreads(); void CleanupWorkerThreads(); // 优化函数声明 SOCKET createOptimizedSocket(const std::string& ip, int port); void optimizedSendToKore(const char* data, uint16_t len, e_PacketType type); DWORD WINAPI highPerformancePacketProcessor(LPVOID lpParam); DWORD WINAPI koreConnectionMainOptimized(LPVOID lpParam); bool ApplyHookOptimized(); void initOptimized(); void finishOptimized(); void DelayedHookApplication(); // IOCP优化器 class IOCPOptimizer { private: HANDLE iocp_handle; public: IOCPOptimizer() : iocp_handle(NULL) {} bool initialize() { iocp_handle = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); return iocp_handle != NULL; } bool associateSocket(SOCKET socket) { return CreateIoCompletionPort((HANDLE)socket, iocp_handle, 0, 0) != NULL; } HANDLE getHandle() { return iocp_handle; } ~IOCPOptimizer() { if (iocp_handle) { CloseHandle(iocp_handle); } } }; IOCPOptimizer iocp_optimizer; // 异步I/O初始化 bool InitializeAsyncIO() { // 创建IOCP句柄 iocpHandle = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, WORKER_THREAD_COUNT); if (iocpHandle == NULL) { cout << "[错误] 创建IOCP句柄失败: " << GetLastError() << endl; return false; } // 预分配异步操作上下文 for (int i = 0; i < MAX_ASYNC_OPS; ++i) { AsyncOperationContext* context = new AsyncOperationContext(); asyncContexts.push_back(context); freeContexts.push(context); } cout << "[成功] 异步I/O初始化完成,预分配 " << MAX_ASYNC_OPS << " 个上下文" << endl; return true; } // 清理异步I/O资源 void CleanupAsyncIO() { if (iocpHandle) { CloseHandle(iocpHandle); iocpHandle = NULL; } // 清理异步上下文 for (auto context : asyncContexts) { delete context; } asyncContexts.clear(); // 清空空闲队列 while (!freeContexts.empty()) { AsyncOperationContext* context = nullptr; freeContexts.try_pop(context); } } // 获取异步操作上下文 AsyncOperationContext* GetAsyncContext() { AsyncOperationContext* context = nullptr; if (freeContexts.try_pop(context)) { context->inUse.store(true, memory_order_relaxed); return context; } // 如果没有空闲上下文,动态创建一个(应该很少发生) lock_guard<mutex> lock(contextMutex); context = new AsyncOperationContext(); context->inUse.store(true, memory_order_relaxed); asyncContexts.push_back(context); cout << "[警告] 动态创建异步上下文,当前总数: " << asyncContexts.size() << endl; return context; } // 归还异步操作上下文 void ReturnAsyncContext(AsyncOperationContext* context) { if (context) { context->reset(); freeContexts.push(context); } } // 提交异步接收操作 bool PostAsyncRecv(SOCKET socket) { AsyncOperationContext* context = GetAsyncContext(); if (!context) { cout << "[错误] 无法获取异步上下文" << endl; return false; } context->socket = socket; context->wsaBuf.buf = context->buffer; context->wsaBuf.len = MAX_PACKET_SIZE; context->bytesTransferred = 0; context->flags = 0; DWORD bytesReceived = 0; // 使用WSARecv进行异步接收 int result = WSARecv(socket, &context->wsaBuf, 1, &bytesReceived, &context->flags, &context->overlapped, NULL); if (result == SOCKET_ERROR) { int error = WSAGetLastError(); if (error != WSA_IO_PENDING) { cout << "[错误] WSARecv失败: " << error << endl; ReturnAsyncContext(context); return false; } } return true; } // 工作线程处理函数 void WorkerThreadProc() { while (workersRunning.load(memory_order_acquire)) { DWORD bytesTransferred = 0; ULONG_PTR completionKey = 0; LPOVERLAPPED overlapped = nullptr; // 等待IOCP完成事件 BOOL success = GetQueuedCompletionStatus(iocpHandle, &bytesTransferred, &completionKey, &overlapped, INFINITE); if (!workersRunning.load(memory_order_acquire)) { break; } if (!overlapped) { // 收到退出信号 continue; } // 获取异步上下文 AsyncOperationContext* context = CONTAINING_RECORD(overlapped, AsyncOperationContext, overlapped); if (!success) { DWORD error = GetLastError(); if (error != WAIT_TIMEOUT) { cout << "[错误] IOCP操作失败: " << error << endl; // 处理连接断开 if (context->socket == koreClient.load(memory_order_acquire)) { koreClient.store(INVALID_SOCKET, memory_order_release); koreClientIsAlive.store(false, memory_order_release); } } ReturnAsyncContext(context); continue; } // 处理接收到的数据 if (bytesTransferred > 0) { // 处理数据包逻辑 char* data = context->buffer; int remaining = bytesTransferred; while (remaining >= 3) { char packet_type = data[0]; uint16_t packet_len = *reinterpret_cast<uint16_t*>(data + 1); if (remaining < 3 + packet_len) break; if (packet_type == 'S' && packet_len > 0) { // 发送到RO客户端 auto* sendFunc = reinterpret_cast<SendToClientFunc>(CLIENT_SUB_ADDRESS); auto* instanceR = reinterpret_cast<originalInstanceR>(CRAG_CONNECTION_INSTANCE_R_ADDRESS); if (sendFunc && instanceR) { void* instance = instanceR(); if (instance) { sendFunc(instance, packet_len, data + 3); } } } int packet_total_size = 3 + packet_len; data += packet_total_size; remaining -= packet_total_size; } // 继续提交异步接收 if (context->socket != INVALID_SOCKET) { PostAsyncRecv(context->socket); } } else { // 连接关闭 if (context->socket == koreClient.load(memory_order_acquire)) { koreClient.store(INVALID_SOCKET, memory_order_release); koreClientIsAlive.store(false, memory_order_release); } ReturnAsyncContext(context); } } } // 初始化工作线程池 bool InitializeWorkerThreads() { workersRunning.store(true, memory_order_release); for (int i = 0; i < WORKER_THREAD_COUNT; ++i) { workerThreads.emplace_back(WorkerThreadProc); } cout << "[成功] 启动 " << WORKER_THREAD_COUNT << " 个工作线程" << endl; return true; } // 清理工作线程池 void CleanupWorkerThreads() { workersRunning.store(false, memory_order_release); // 向所有线程发送退出信号 for (size_t i = 0; i < workerThreads.size(); ++i) { PostQueuedCompletionStatus(iocpHandle, 0, 0, NULL); } // 等待线程退出 for (auto& thread : workerThreads) { if (thread.joinable()) { thread.join(); } } workerThreads.clear(); cout << "[信息] 工作线程池已清理" << endl; } // 优化的recv钩子函数 int WINAPI hooked_recv(SOCKET s, char* buf, int len, int flags) { int result = original_recv(s, buf, len, flags); if (result > 0) { roServer.store(s, memory_order_release); // 使用内存池避免动态分配 auto packet_node = packetPool.acquire(); if (packet_node) { packet_node->size = static_cast<uint16_t>(result); memcpy(packet_node->data, buf, result); // 构建发送数据 char send_buf[3 + MAX_PACKET_SIZE]; send_buf[0] = 'R'; *reinterpret_cast<uint16_t*>(send_buf + 1) = packet_node->size; memcpy(send_buf + 3, packet_node->data, packet_node->size); // 非阻塞写入环形缓冲区 if (!sendBuffer.push(send_buf, 3 + packet_node->size)) { // 缓冲区满,直接发送到RO服务器(降级处理) SOCKET ro_sock = roServer.load(memory_order_acquire); if (ro_sock != INVALID_SOCKET) { send(ro_sock, buf, result, 0); } } packetPool.release(packet_node); } } return result; } // 控制台分配 void AllocateConsole() { AllocConsole(); freopen_s((FILE**)stdout, "CONOUT$", "w", stdout); freopen_s((FILE**)stderr, "CONOUT$", "w", stderr); freopen_s((FILE**)stdin, "CONIN$", "r", stdin); #ifdef UNICODE SetConsoleTitle(L"xKore优化版 - 调试控制台"); #else SetConsoleTitle("xKore优化版 - 调试控制台"); #endif } // 调试输出 void debug(const char* msg) { cout << "[调试] " << msg << endl; } // 创建默认配置 bool CreateDefaultConfig(const std::string& filename) { ofstream fout(filename); if (!fout.is_open()) { cout << "[错误] 无法创建配置文件: " << filename << endl; return false; } fout << "# xKore服务器配置\n"; fout << "koreServerIP=127.0.0.1\n"; fout << "koreServerPort=2350\n"; fout << "\n"; fout << "# 多客户端配置\n"; fout << "# 如果为true, 每次执行时在终端询问端口\n"; fout << "# 如果为false, 总是使用koreServerPort的默认端口\n"; fout << "allowMultiClient=true"; fout.close(); cout << "[成功] 默认配置文件已创建: " << filename << endl; return true; } // 加载配置 bool LoadConfig(const std::string& filename) { ifstream fin(filename); if (!fin.is_open()) { if (!CreateDefaultConfig(filename)) { return false; } cout << "\n*** 注意: 使用前请配置 '" << filename << "' 文件! ***" << endl; cout << "========================\n" << endl; fin.open(filename); if (!fin.is_open()) { cout << "[错误] 无法打开创建的配置文件: " << filename << endl; return false; } } string line; unordered_map<string, string> mapa; while (getline(fin, line)) { if (line.empty()) continue; if (line[0] == '#' || line[0] == ';') continue; size_t pos = line.find('='); if (pos == string::npos) continue; string chave = line.substr(0, pos); string valor = line.substr(pos + 1); while (!chave.empty() && isspace(chave.back())) chave.pop_back(); while (!valor.empty() && isspace(valor.front())) valor.erase(0, 1); while (!valor.empty() && isspace(valor.back())) valor.pop_back(); mapa[chave] = valor; } fin.close(); if (mapa.count("koreServerIP") == 0 || mapa.count("koreServerPort") == 0) { cout << "[错误] config_recv.txt中缺少必要的键。需要:\n" << " koreServerIP\n" << " koreServerPort\n"; return false; } try { koreServerIP = mapa.at("koreServerIP"); koreServerPort = static_cast<DWORD>(stoul(mapa.at("koreServerPort"), nullptr, 10)); if (mapa.count("allowMultiClient") > 0) { string allowMultiStr = mapa.at("allowMultiClient"); transform(allowMultiStr.begin(), allowMultiStr.end(), allowMultiStr.begin(), ::tolower); allowMultiClient = (allowMultiStr == "true" || allowMultiStr == "1" || allowMultiStr == "yes"); } } catch (exception& e) { cout << "[错误] 转换值时出现异常: " << e.what() << endl; return false; } cout << "[信息] 配置加载成功:\n\n" << " koreServerIP = " << koreServerIP << "\n" << " koreServerPort = " << koreServerPort << "\n" << " allowMultiClient = " << (allowMultiClient ? "true" : "false") << endl; return true; } // 应用Hook(优化版) bool ApplyHookOptimized() { if (original_recv != nullptr) { return true; // 已经hook } recv_func_t* recv_ptr = reinterpret_cast<recv_func_t*>(RECV_PTR_ADDRESS); original_recv = *recv_ptr; if (original_recv == nullptr) { cout << "错误: 原始recv指针为空!" << endl; return false; } *recv_ptr = hooked_recv; // 验证hook是否成功 if (*recv_ptr == hooked_recv) { hook_applied.store(true, memory_order_release); cout << "Hook应用成功!" << endl; return true; } return false; } // 延迟应用Hook函数 void DelayedHookApplication() { cout << "[信息] 等待3秒后应用Hook(避免强壳NP检测)..." << endl; // 等待3秒 this_thread::sleep_for(chrono::milliseconds(HOOK_DELAY)); cout << "[信息] 开始应用Hook..." << endl; if (ApplyHookOptimized()) { cout << "[成功] 延迟Hook应用成功" << endl; hook_delayed.store(true, memory_order_release); } else { cout << "[错误] 延迟Hook应用失败" << endl; } } // 移除Hook void RemoveHook() { if (original_recv) { recv_func_t* recv_ptr = reinterpret_cast<recv_func_t*>(RECV_PTR_ADDRESS); *recv_ptr = original_recv; cout << "Hook已移除!" << endl; } } // 检查socket连接状态 bool isConnected(SOCKET s) { if (s == INVALID_SOCKET) return false; fd_set readfds; FD_ZERO(&readfds); FD_SET(s, &readfds); timeval timeout = { 0, 0 }; int result = select(0, &readfds, NULL, NULL, &timeout); if (result == SOCKET_ERROR) return false; return true; } // 创建优化socket SOCKET createOptimizedSocket(const std::string& ip, int port) { sockaddr_in addr; SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == INVALID_SOCKET) { cout << "[错误] 创建socket失败: " << WSAGetLastError() << endl; return INVALID_SOCKET; } // 关键TCP优化参数 int nodelay = 1; if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char*)&nodelay, sizeof(nodelay)) == SOCKET_ERROR) { cout << "[警告] 设置TCP_NODELAY失败: " << WSAGetLastError() << endl; } // 设置发送缓冲区大小 int send_buf_size = 64 * 1024; setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char*)&send_buf_size, sizeof(send_buf_size)); // 设置接收缓冲区大小 int recv_buf_size = 64 * 1024; setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*)&recv_buf_size, sizeof(recv_buf_size)); addr.sin_family = AF_INET; addr.sin_port = htons(static_cast<u_short>(port)); addr.sin_addr.s_addr = inet_addr(ip.c_str()); // 非阻塞连接 unsigned long mode = 1; ioctlsocket(sock, FIONBIO, &mode); int connect_result = connect(sock, (struct sockaddr*)&addr, sizeof(addr)); // 等待连接完成 fd_set writefds; FD_ZERO(&writefds); FD_SET(sock, &writefds); timeval timeout = { 3, 0 }; // 3秒超时 int select_result = select(0, NULL, &writefds, NULL, &timeout); if (select_result <= 0) { cout << "[错误] 连接超时或失败: " << WSAGetLastError() << endl; closesocket(sock); return INVALID_SOCKET; } // 检查socket错误 int error = 0; int error_len = sizeof(error); getsockopt(sock, SOL_SOCKET, SO_ERROR, (char*)&error, &error_len); if (error != 0) { cout << "[错误] 连接失败: " << error << endl; closesocket(sock); return INVALID_SOCKET; } // 恢复阻塞模式 mode = 0; ioctlsocket(sock, FIONBIO, &mode); // 关联到IOCP if (iocpHandle) { CreateIoCompletionPort((HANDLE)sock, iocpHandle, 0, 0); } return sock; } // 优化数据发送 void optimizedSendToKore(const char* data, uint16_t len, e_PacketType type) { if (!koreClientIsAlive.load(memory_order_acquire)) return; char header[3]; header[0] = (type == RECEIVED) ? 'R' : 'S'; *reinterpret_cast<uint16_t*>(header + 1) = len; // 先尝试写入header if (!sendBuffer.push(header, 3)) { return; // 缓冲区满,丢弃数据 } // 再写入数据 if (!sendBuffer.push(data, len)) { // 回滚header写入 char temp[3]; sendBuffer.pop(temp, 3); } } // 高性能封包处理线程 DWORD WINAPI highPerformancePacketProcessor(LPVOID lpParam) { char local_buf[4096]; atomic_dword last_send_time(GetTickCount()); atomic_dword last_ping_time(GetTickCount()); while (keepMainThread.load(memory_order_acquire)) { DWORD current_time = GetTickCount(); // 处理发送缓冲区 uint32_t available = sendBuffer.available_read(); if (available > 0) { SOCKET kore_sock = koreClient.load(memory_order_acquire); if (kore_sock != INVALID_SOCKET) { uint32_t bytes_read = sendBuffer.pop(local_buf, min(available, sizeof(local_buf))); if (bytes_read > 0) { int sent = send(kore_sock, local_buf, bytes_read, 0); if (sent == SOCKET_ERROR) { // 发送失败,可能连接已断开 koreClient.store(INVALID_SOCKET, memory_order_release); koreClientIsAlive.store(false, memory_order_release); } else { last_send_time.store(current_time, memory_order_relaxed); } } } } // 定期Ping(保持连接活跃) if (current_time - last_ping_time.load(memory_order_relaxed) > PING_INTERVAL) { SOCKET kore_sock = koreClient.load(memory_order_acquire); if (kore_sock != INVALID_SOCKET) { char ping_packet[3] = { 'K', 0, 0 }; send(kore_sock, ping_packet, 3, 0); } last_ping_time.store(current_time, memory_order_relaxed); } // 智能休眠:有数据时忙等待,无数据时短暂休眠 if (available == 0) { Sleep(1); // 1ms休眠减少CPU占用 } } return 0; } // 主连接线程(优化版) DWORD WINAPI koreConnectionMainOptimized(LPVOID lpParam) { // 等待Hook应用完成 while (!hook_delayed.load(memory_order_acquire) && keepMainThread.load(memory_order_acquire)) { cout << "[信息] 等待Hook应用完成..." << endl; Sleep(500); } if (!hook_applied.load(memory_order_acquire)) { cout << "[错误] Hook未应用,连接线程退出" << endl; return 1; } // 创建专用的封包处理线程 HANDLE packet_thread = CreateThread(NULL, 0, highPerformancePacketProcessor, NULL, CREATE_SUSPENDED, NULL); if (!packet_thread) { cout << "[错误] 创建封包处理线程失败: " << GetLastError() << endl; return 1; } // 设置线程优先级 SetThreadPriority(packet_thread, THREAD_PRIORITY_ABOVE_NORMAL); SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL); // 禁用线程库通知减少开销 DisableThreadLibraryCalls(GetModuleHandle(NULL)); // 启动封包处理线程 ResumeThread(packet_thread); char recv_buf[8192]; atomic_dword last_connect_attempt(0); atomic_dword last_activity_time(GetTickCount()); cout << "[信息] xKore连接线程已启动" << endl; while (keepMainThread.load(memory_order_acquire)) { DWORD current_time = GetTickCount(); SOCKET current_kore_client = koreClient.load(memory_order_acquire); // 连接管理 if (current_kore_client == INVALID_SOCKET || !isConnected(current_kore_client)) { if (current_time - last_connect_attempt.load(memory_order_relaxed) > RECONNECT_INTERVAL) { if (current_kore_client != INVALID_SOCKET) { shutdown(current_kore_client, SD_BOTH); closesocket(current_kore_client); } SOCKET new_socket = createOptimizedSocket(koreServerIP, koreServerPort); if (new_socket != INVALID_SOCKET) { koreClient.store(new_socket, memory_order_release); koreClientIsAlive.store(true, memory_order_release); imalive.store(true, memory_order_release); last_activity_time.store(current_time, memory_order_relaxed); // 提交异步接收操作 if (iocpHandle) { PostAsyncRecv(new_socket); } cout << "[成功] 已连接到xKore服务器 " << koreServerIP << ":" << koreServerPort << endl; } else { koreClientIsAlive.store(false, memory_order_release); imalive.store(false, memory_order_release); cout << "[错误] 连接xKore服务器失败" << endl; } last_connect_attempt.store(current_time, memory_order_relaxed); } Sleep(100); // 连接失败时短暂休眠 continue; } // 检查超时 if (current_time - last_activity_time.load(memory_order_relaxed) > TIMEOUT) { cout << "[警告] 连接超时,重新连接..." << endl; koreClient.store(INVALID_SOCKET, memory_order_release); continue; } // 如果没有使用异步I/O,则使用传统的recv if (!iocpHandle) { int bytes_received = recv(current_kore_client, recv_buf, sizeof(recv_buf), 0); if (bytes_received > 0) { last_activity_time.store(current_time, memory_order_relaxed); // 处理接收到的封包 const char* data_ptr = recv_buf; int remaining = bytes_received; while (remaining >= 3) { char packet_type = data_ptr[0]; uint16_t packet_len = *reinterpret_cast<const uint16_t*>(data_ptr + 1); if (remaining < 3 + packet_len) break; // 数据不完整 if (packet_type == 'S' && packet_len > 0) { // 发送到RO客户端 auto* sendFunc = reinterpret_cast<SendToClientFunc>(CLIENT_SUB_ADDRESS); auto* instanceR = reinterpret_cast<originalInstanceR>(CRAG_CONNECTION_INSTANCE_R_ADDRESS); if (sendFunc && instanceR) { void* instance = instanceR(); if (instance) { sendFunc(instance, packet_len, const_cast<char*>(data_ptr + 3)); } } } int packet_total_size = 3 + packet_len; data_ptr += packet_total_size; remaining -= packet_total_size; } } else if (bytes_received == 0) { // 连接关闭 cout << "[信息] xKore服务器断开连接" << endl; shutdown(current_kore_client, SD_BOTH); closesocket(current_kore_client); koreClient.store(INVALID_SOCKET, memory_order_release); koreClientIsAlive.store(false, memory_order_release); imalive.store(false, memory_order_release); } else if (bytes_received == SOCKET_ERROR) { int error = WSAGetLastError(); if (error != WSAEWOULDBLOCK) { cout << "[错误] 接收数据失败: " << error << endl; koreClient.store(INVALID_SOCKET, memory_order_release); } } } // 轻微休眠避免过高CPU占用 Sleep(SLEEP_TIME); } // 清理线程 keepMainThread.store(false, memory_order_release); WaitForSingleObject(packet_thread, 5000); CloseHandle(packet_thread); cout << "[信息] xKore连接线程已退出" << endl; return 0; } // 获取用户端口(多客户端模式) DWORD GetUserPort() { char input[256]; cout << "\n[多客户端模式]" << endl; cout << "请输入xKore服务器端口(默认: " << koreServerPort << "): "; if (fgets(input, sizeof(input), stdin)) { input[strcspn(input, "\r\n")] = 0; if (strlen(input) == 0) { cout << "使用默认端口: " << koreServerPort << endl; return koreServerPort; } int inputPort = atoi(input); if (inputPort > 0 && inputPort <= 65535) { cout << "使用自定义端口: " << inputPort << endl; return static_cast<DWORD>(inputPort); } else { cout << "无效端口! 使用默认端口: " << koreServerPort << endl; return koreServerPort; } } cout << "读取错误! 使用默认端口: " << koreServerPort << endl; return koreServerPort; } // 初始化函数 void initOptimized() { AllocateConsole(); cout << "=== xKore优化版 ===" << endl; cout << "架构: x86 (32位)" << endl; cout << "优化: 原子操作 + 内存池 + 环形缓冲区 + 异步I/O" << endl; cout << "特性: 3秒延迟Hook(避免强壳检测)" << endl; // 初始化Winsock WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { cout << "[错误] Winsock初始化失败" << endl; return; } // 加载配置 if (!LoadConfig("config_recv.txt")) { cout << "[致命] 加载配置文件失败" << endl; keepMainThread.store(false, memory_order_release); return; } // 多客户端模式 if (allowMultiClient) { koreServerPort = GetUserPort(); } // 初始化异步I/O系统 if (!InitializeAsyncIO()) { cout << "[警告] 异步I/O初始化失败,使用传统模式" << endl; } else { // 初始化工作线程池 if (!InitializeWorkerThreads()) { cout << "[警告] 工作线程池初始化失败,使用传统模式" << endl; CleanupAsyncIO(); } } // 创建延迟Hook应用线程 HANDLE hook_thread = CreateThread(NULL, 0, [](LPVOID) -> DWORD { DelayedHookApplication(); return 0; }, NULL, 0, NULL); if (hook_thread) { cout << "[信息] 延迟Hook线程已启动" << endl; CloseHandle(hook_thread); // 不需要保持句柄 } else { cout << "[错误] 创建延迟Hook线程失败: " << GetLastError() << endl; // 直接应用Hook作为备选方案 cout << "[信息] 尝试直接应用Hook..." << endl; ApplyHookOptimized(); } // 创建优化版主线程 HANDLE hThread = CreateThread(NULL, 0, koreConnectionMainOptimized, NULL, 0, NULL); if (hThread) { cout << "[成功] xKore主线程已启动" << endl; CloseHandle(hThread); // 不需要保持句柄 } else { cout << "[错误] 创建主线程失败: " << GetLastError() << endl; keepMainThread.store(false, memory_order_release); } cout << "====================\n" << endl; } // 清理函数 void finishOptimized() { cout << "[信息] 开始清理资源..." << endl; keepMainThread.store(false, memory_order_release); // 等待线程退出 Sleep(100); // 清理工作线程池异步I/O CleanupWorkerThreads(); CleanupAsyncIO(); // 关闭socket连接 SOCKET sock = koreClient.exchange(INVALID_SOCKET, memory_order_acq_rel); if (sock != INVALID_SOCKET) { shutdown(sock, SD_BOTH); closesocket(sock); } sock = roServer.exchange(INVALID_SOCKET, memory_order_acq_rel); if (sock != INVALID_SOCKET) { closesocket(sock); } // 移除hook if (original_recv) { RemoveHook(); } // 清理Winsock WSACleanup(); cout << "[信息] 资源清理完成" << endl; } // DLL主入口 BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: // 禁用线程通知以减少开销 DisableThreadLibraryCalls(hModule); initOptimized(); break; case DLL_PROCESS_DETACH: finishOptimized(); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: break; } return TRUE; }针对 RO 的1 对 1 单 IP 连接、高频小封包场景,IOCP 的 “恰到好处” 核心是:聚焦 “单连接下的高频 IO 效率”,砍掉多连接场景的冗余设计,用最小的资源开销解决 “卡顿、丢包” 问题,避免为 “用而用” 的过度优化。具体需在 6 个关键环节做到精准控制,既保留 IOCP 的核心优势,又不引入不必要的复杂度: 一、完成端口(IOCP)初始化:极简配置,不浪费内核资源 单连接场景下,IOCP 无需配置多连接的 “高并发参数”,核心是 “轻量化创建 + 绑定单 Socket”,避免内核资源闲置: 并发线程数设为 1,而非 CPU 核心数CreateIoCompletionPort 的第 4 个参数(NumberOfConcurrentThreads)控制允许同时处理 IO 事件的线程数。多连接场景会设为 CPU 核心数(如 4 核设 4),但单连接下 IO 事件是 “串行触发”(同一时间仅 1 个小封包待处理),设为1即可 —— 多线程反而会导致 “线程切换开销”(比如 2 个线程抢 1 个 IO 事件,浪费 CPU)。文档中IOCPOptimizer::initialize()用了默认的0(等于 CPU 核心数),可优化为1,更贴合单连接: cpp 运行 iocp_handle = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1); // 最后一个参数设为1 仅关联 1 个目标 Socket,不做批量绑定单连接场景下,仅需将 RO 客户端与服务器的 Socket(或 xKore 代理的 Socket)关联到 IOCP,无需设计 “批量 Socket 绑定逻辑”(如循环绑定多个连接)。文档中associateSocket()单次绑定 1 个 Socket 的逻辑已适配,无需额外扩展。 二、线程池设计:1 个工作线程足够,拒绝 “多线程冗余” IOCP 的线程池是 “事件消费者”,单连接下高频小封包的 IO 事件是 “连续且串行” 的,1 个工作线程即可高效处理,多线程反而会引入 “锁竞争”(如抢读环形缓冲区),属于过度优化: 固定 1 个 IO 工作线程,不动态增减无需设计 “根据 IO 压力动态创建 / 销毁线程” 的逻辑(多连接场景才需要),直接创建 1 个常驻线程处理 IO 事件即可。比如文档中的highPerformancePacketProcessor线程,可固定为 1 个,无需用线程池库(如CreateThreadPool)—— 代码中SetThreadPriority设为THREAD_PRIORITY_ABOVE_NORMAL是合理的(保证 IO 处理优先级高于普通逻辑,避免小封包延迟),但无需多线程。 线程与 IO 事件 “一对一绑定”,避免线程切换单线程处理所有 IO 事件(读 / 写 / 错误),无需拆分 “读线程”“写线程”—— 拆分后会增加 “线程间通信开销”(如写线程通知读线程处理数据),反而降低效率。文档中 “1 个线程处理发送缓冲区 + Ping + 超时检测” 的逻辑已适配,无需修改。 三、IO 请求投递:预投递 + 小缓冲区,适配高频小封包 RO 的小封包(10~512 字节)若 “每次投递 1 个 IO 请求”,会导致系统调用(WSARecv/WSASend)频繁,反而增加开销。需用 “预投递 + 固定小缓冲区” 优化,平衡效率与资源: 预投递 1 个读请求,而非多次投递单连接下,Socket 接收缓冲区的小封包是 “连续到达” 的,可预先投递 1 个WSARecv请求(挂起等待数据),数据到达后处理完再投递下 1 个 —— 避免 “每收到 1 个小封包就投递 1 次请求” 的高频系统调用。示例逻辑: cpp 运行 // 预投递读请求(初始化时执行1次) OVERLAPPED ov; memset(&ov, 0, sizeof(ov)); char recv_buf[512]; // 适配RO小封包,不用8192字节大缓冲区 WSARecv(sock, &wsabuf, 1, NULL, &flags, &ov, NULL); // 处理完成事件后,再次投递下1个请求 while (keepRunning) { GetQueuedCompletionStatus(iocp_handle, &bytesTransferred, &key, &ov, INFINITE); processSmallPacket(recv_buf, bytesTransferred); // 处理小封包 WSARecv(sock, &wsabuf, 1, NULL, &flags, &ov, NULL); // 再次预投递 } 这里缓冲区设为512 字节(RO 小封包最大通常不超过 512),比文档中recv_buf[8192]更节省内存,且避免 “大缓冲区空闲浪费”。 写请求 “批量合并”,减少 WSASend 调用高频小封包发送时,若每次调用WSASend发送 1 个小封包(如 10 字节),系统调用开销占比极高。可结合文档中的环形缓冲区(sendBuffer) ,积累多个小封包(如累计到 1KB 或等待 1ms)后,一次性调用WSASend发送 —— 但需注意 “延迟平衡”(累计时间不超过 1ms,避免 RO 实时交互卡顿)。文档中 “有数据就发送” 的逻辑可微调:增加 “最小累计字节数”(如 128 字节),减少系统调用次数,又不影响延迟。 四、缓冲区与内存管理:贴合小封包,避免 “大缓冲冗余” RO 的小封包不需要大缓冲区,过度分配会导致内存浪费;同时需避免动态内存分配(高频小封包易引发内存碎片),文档中的内存池已适配,需进一步贴合场景: Socket 缓冲区设为 64KB,不盲目调大SO_SNDBUF/SO_RCVBUF 的大小需适配小封包:设为 64KB 足够(RO 每秒数百个小封包,总流量仅几十 KB),设为 128KB 或更大反而会增加 “缓冲区数据拷贝开销”(内核到用户态)。文档中send_buf_size = 64 * 1024的配置已恰到好处,无需修改。 内存池单包大小设为 512 字节,而非 8KB文档中MAX_PACKET_SIZE = 8192(8KB)过大,RO 小封包最大仅 512 字节,可改为512,减少内存池的内存占用(1024 个包仅 512KB,原 8KB 需 8MB)。同时避免 “大缓冲区拆分小封包” 的逻辑,简化内存池管理。 五、错误处理与降级:简单可靠,不做复杂容错 单连接场景下,IO 错误类型少(如连接断开、超时),无需设计 “复杂的错误重试逻辑”(如多连接的 “故障转移”),做到 “快速检测 + 优雅降级” 即可: 仅处理关键错误,避免冗余判断重点处理 3 类错误:WSAECONNRESET(连接被重置)、WSAETIMEDOUT(超时)、ERROR_NETNAME_DELETED(连接关闭),其他错误直接触发 “重连逻辑”(如文档中的koreClient.store(INVALID_SOCKET))。无需遍历所有 WSA 错误码,减少判断开销。 IOCP 初始化失败时,降级为 “简化异步 IO”若 IOCP 创建失败(如老旧系统不支持),无需崩溃,可降级为 “WSAEventSelect”(比 select 高效,比 IOCP 简单),而非直接用 select。文档中 “IOCP 关联失败仅警告” 的逻辑可优化为降级逻辑,保证兼容性,又不引入过度容错。 六、避免 “为 IOCP 而加的冗余特性” 单连接场景下,多连接 IOCP 的常见特性(如 “连接池”“负载均衡”“多完成端口拆分”)均无需实现,属于典型的过度优化: 不做 “连接池”:单连接无需缓存多个 Socket,直接创建 / 关闭即可; 不做 “多完成端口”:1 个完成端口足够处理单连接,多完成端口会增加内核调度开销; 不做 “IO 事件优先级”:单连接下所有小封包优先级相同(如移动、技能封包无先后),无需设计事件优先级队列。 总结:IOCP “恰到好处” 的核心原则 针对 RO 1 对 1 单连接、高频小封包场景,IOCP 的优化需围绕 “最小资源开销解决核心问题”: 资源上:1 个完成端口 + 1 个工作线程 + 64KB Socket 缓冲区 + 512 字节内存池,不浪费内存与 CPU; 逻辑上:预投递 1 个读请求 + 批量合并写请求 + 简单错误处理,不引入多线程、多完成端口等冗余设计; 目标上:仅解决 “select 轮询开销”“小封包延迟”“缓冲区溢出丢包” 三大问题,不追求 “多连接扩展性”“极致并发” 等无关特性。 这种设计既保留了 IOCP “异步无轮询” 的核心优势(从根源解决卡顿、丢包),又避免了过度优化带来的复杂度与资源浪费,完全适配 RO 的单连接高频小封包场景。
09-24
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值