Files
SimpleRemoter/server/2015Remote/IOCPServer.h

192 lines
5.4 KiB
C
Raw Normal View History

#pragma once
2025-06-08 15:38:41 +08:00
#include "StdAfx.h"
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
#include "Server.h"
2025-05-03 20:57:22 +08:00
#if USING_CTX
#include "zstd/zstd.h"
#endif
#include <Mstcpip.h>
#define NC_CLIENT_CONNECT 0x0001
#define NC_RECEIVE 0x0004
#define NC_RECEIVE_COMPLETE 0x0005 // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// ZLIB ѹ<><D1B9><EFBFBD><EFBFBD>
#include "zlib/zlib.h"
#if USING_LZ4
#include "lz4/lz4.h"
#pragma comment(lib, "lz4/lz4.lib")
#define C_FAILED(p) (0 == (p))
#define C_SUCCESS(p) (!C_FAILED(p))
#define Mcompress(dest, destLen, source, sourceLen) LZ4_compress_default((const char*)source, (char*)dest, sourceLen, *(destLen))
#define Muncompress(dest, destLen, source, sourceLen) LZ4_decompress_safe((const char*)source, (char*)dest, sourceLen, *(destLen))
#else // ZSTD
#include "zstd/zstd.h"
#ifdef _WIN64
#pragma comment(lib, "zstd/zstd_x64.lib")
#else
#pragma comment(lib, "zstd/zstd.lib")
#endif
#define C_FAILED(p) ZSTD_isError(p)
#define C_SUCCESS(p) (!C_FAILED(p))
#define ZSTD_CLEVEL 5
#if USING_CTX
#define Mcompress(dest, destLen, source, sourceLen) ZSTD_compress2(m_Cctx, dest, *(destLen), source, sourceLen)
#define Muncompress(dest, destLen, source, sourceLen) ZSTD_decompressDCtx(m_Dctx, dest, *(destLen), source, sourceLen)
#else
#define Mcompress(dest, destLen, source, sourceLen) ZSTD_compress(dest, *(destLen), source, sourceLen, ZSTD_CLEVEL_DEFAULT)
#define Muncompress(dest, destLen, source, sourceLen) ZSTD_decompress(dest, *(destLen), source, sourceLen)
#endif
#endif
2025-01-31 22:22:16 +08:00
2025-05-03 20:57:22 +08:00
class IOCPServer : public Server
2025-05-03 20:57:22 +08:00
{
protected:
int m_nPort;
SOCKET m_sListenSocket;
HANDLE m_hCompletionPort;
UINT m_ulMaxConnections;
HANDLE m_hListenEvent;
HANDLE m_hListenThread;
BOOL m_bTimeToKill;
HANDLE m_hKillEvent;
ULONG m_ulThreadPoolMin;
ULONG m_ulThreadPoolMax;
ULONG m_ulCPULowThreadsHold;
ULONG m_ulCPUHighThreadsHold;
ULONG m_ulCurrentThread;
ULONG m_ulBusyThread;
#if USING_CTX
ZSTD_CCtx* m_Cctx; // ѹ<><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ZSTD_DCtx* m_Dctx; // <20><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#endif
ULONG m_ulKeepLiveTime;
pfnNotifyProc m_NotifyProc;
pfnOfflineProc m_OfflineProc;
ULONG m_ulWorkThreadCount;
CRITICAL_SECTION m_cs;
ContextObjectList m_ContextConnectionList;
ContextObjectList m_ContextFreePoolList;
private:
static DWORD WINAPI ListenThreadProc(LPVOID lParam);
static DWORD WINAPI WorkThreadProc(LPVOID lParam);
BOOL InitializeIOCP(VOID);
VOID OnAccept();
2025-06-08 15:38:41 +08:00
PCONTEXT_OBJECT AllocateContext(SOCKET s);
VOID RemoveStaleContext(CONTEXT_OBJECT* ContextObject);
VOID MoveContextToFreePoolList(CONTEXT_OBJECT* ContextObject);
VOID PostRecv(CONTEXT_OBJECT* ContextObject);
BOOL HandleIO(IOType PacketFlags, PCONTEXT_OBJECT ContextObject, DWORD dwTrans);
BOOL OnClientInitializing(PCONTEXT_OBJECT ContextObject, DWORD dwTrans);
BOOL OnClientReceiving(PCONTEXT_OBJECT ContextObject, DWORD dwTrans);
VOID OnClientPreSending(CONTEXT_OBJECT* ContextObject, PBYTE szBuffer, size_t ulOriginalLength);
BOOL OnClientPostSending(CONTEXT_OBJECT* ContextObject, ULONG ulCompressedLength);
int AddWorkThread(int n) {
EnterCriticalSection(&m_cs);
m_ulWorkThreadCount += n;
int ret = m_ulWorkThreadCount;
LeaveCriticalSection(&m_cs);
return ret;
}
2019-01-10 19:35:03 +08:00
public:
IOCPServer(void);
~IOCPServer(void);
int GetPort() const override {
return m_nPort;
}
UINT StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, USHORT uPort);
2025-06-08 15:38:41 +08:00
VOID Send2Client(CONTEXT_OBJECT* ContextObject, PBYTE szBuffer, ULONG ulOriginalLength) {
OnClientPreSending(ContextObject, szBuffer, ulOriginalLength);
}
2024-12-31 03:11:26 +08:00
void UpdateMaxConnection(int maxConn);
void Destroy();
2025-05-03 20:57:22 +08:00
void Disconnect(CONTEXT_OBJECT *ctx){}
};
2025-05-03 20:57:22 +08:00
typedef IOCPServer ISocketBase;
2025-01-31 22:22:16 +08:00
typedef IOCPServer CIOCPServer;
typedef CONTEXT_OBJECT ClientContext;
#define m_Socket sClientSocket
#define m_DeCompressionBuffer InDeCompressedBuffer
2025-06-08 15:38:41 +08:00
// <20><><EFBFBD>ж<EFBFBD>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD>ĶԻ<C4B6><D4BB><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD>
class CDialogBase : public CDialog {
public:
CONTEXT_OBJECT* m_ContextObject;
Server* m_iocpServer;
2025-06-08 15:38:41 +08:00
CString m_IPAddress;
bool m_bIsClosed;
bool m_bIsProcessing;
2025-06-08 15:38:41 +08:00
HICON m_hIcon;
CDialogBase(UINT nIDTemplate, CWnd* pParent, Server* pIOCPServer, CONTEXT_OBJECT* pContext, int nIcon) :
m_bIsClosed(false), m_bIsProcessing(false),
2025-06-08 15:38:41 +08:00
m_ContextObject(pContext),
m_iocpServer(pIOCPServer),
CDialog(nIDTemplate, pParent) {
sockaddr_in sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
int nSockAddrLen = sizeof(sockaddr_in);
BOOL bResult = getpeername(m_ContextObject->sClientSocket, (SOCKADDR*)&sockAddr, &nSockAddrLen);
m_IPAddress = bResult != INVALID_SOCKET ? inet_ntoa(sockAddr.sin_addr) : "";
m_hIcon = nIcon > 0 ? LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(nIcon)) : NULL;
}
virtual ~CDialogBase(){}
2025-06-08 15:38:41 +08:00
public:
virtual void OnReceiveComplete(void) = 0;
// <20><><EFBFBD><EFBFBD>Ϊ<EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>ڽ<EFBFBD><DABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void MarkReceiving(bool recv = true) {
m_bIsProcessing = recv;
}
bool IsProcessing() const {
return m_bIsProcessing;
}
2025-06-08 15:38:41 +08:00
void OnClose() {
m_bIsClosed = true;
while (m_bIsProcessing)
Sleep(200);
if(m_hIcon) DestroyIcon(m_hIcon);
m_hIcon = NULL;
2025-06-08 15:38:41 +08:00
CDialog::OnClose();
if (GetSafeHwnd())
DestroyWindow();
}
virtual void PostNcDestroy() override
{
2025-06-08 15:38:41 +08:00
delete this;
}
// ȡ<><C8A1> SOCKET <20><>ȡ<EFBFBD><C8A1><EFBFBD>ú<EFBFBD><C3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>ε<EFBFBD><CEB5><EFBFBD>
void CancelIO(){
m_bIsClosed = TRUE;
m_ContextObject->CancelIO();
2025-06-08 15:38:41 +08:00
}
};
typedef CDialogBase DialogBase;
BOOL ParseReceivedData(CONTEXT_OBJECT* ContextObject, DWORD dwTrans, pfnNotifyProc m_NotifyProc);
BOOL WriteContextData(CONTEXT_OBJECT* ContextObject, PBYTE szBuffer, size_t ulOriginalLength);