www.pudn.com > back.rar > iocpnet.h
//BravoNet.h /**************************************************************************************** _GENERAL FILE : BravoNet.H AUTHOR : WON-BYUM, PARK (GR8WON) _DATE CREATE : APRIL 7th, 2002 MODIFIED : JULY , 2004 ****************************************************************************************/ #ifndef __BRAVONET_H__ #define __BRAVONET_H__ //#define _WIN32_WINNT 0x403 //must need for InitializeCriticalSectionAndSpinCount uses //includes #include#include //CGen_Debug using namespace std; #include //multiserver defines #define BRAVO_GATEWAY_KEY (10000) //gateway key (used in zoneserver & gateway) #define BRAVO_ZONEMSG_KEY (50000) #define BRAVO_MAXGATEWAY (5) //Max gateways per one zoneserver #define BRAVO_MAXGATEWAY_USER (512*3) //Max user per gateways #define BRAVO_MAX_MULTI_SERVER (72) //Max listen, connect multi server count //base service defines #define SOCKET_MAX_LISTEN BRAVO_MAX_MULTI_SERVER //Max listen socket //receive & send buffer defines--------------------------------------------------------------------------------------------- #define MAX_ONETIME_RECEIVE_BUFFER (4096 ) //Max Message size #define IOCP_MAX_SIZE_PER_MESSAGES (512*6) //Max write size (queue document must greater then this define #define MAX_READ_QUEUE_LIST (12) //Read queue list counts #define MAX_READ_QUEUE_SIZE (1024*1024*12) //IOCPs overlapped Event defines--------------------------------------------------------------------------------------------- #define IOCP_EVENT_NONE (0) //overlapped events #define IOCP_EVENT_READ (1) // #define IOCP_EVENT_WRITE (2) // //IOCPs & threads defines--------------------------------------------------------------------------------------------- #define IOCP_THREADS_PER_CPU (8) //desire to create thread for IOCPs #define IOCP_MAX_CLIENT_ACCPET (512*3) //Max clients //messages related defines #define IOCP_MAX_CLIENT_MESSAGES (512) //MAX message counts (total message varibles) //debug related #define IOCP_DEBUG //open when debug #define IOCP_MSG_SEQ //open message sequence check /**************************************************************************************** buffers & overlapped struct OVERLAPPED_BASE */ struct OVERLAPPED_BASE : public WSAOVERLAPPED { OVERLAPPED_BASE() { Internal = 0; InternalHigh = 0; Offset = 0; OffsetHigh = 0; hEvent = 0; m_iClient = 0; m_sEvent = IOCP_EVENT_NONE; } USHORT m_sEvent; //IOCPs Event //IOCP_EVENT_NONE //IOCP_EVENT_READ //IOCP_EVENT_WRITE WORD m_wID; //Current ID (optional uses) //when writing, m_wID is the array number of writing queue UINT m_iClient; //Client array ID UINT m_iWritten; //written size (used in write process) }; /************************************************************************************ struct SXClientBuffer */ #define XBUFFER_EMPTY (0) //for client read & write struct SXClientBuffer { SXClientBuffer() { m_dwSize=0; m_szBuffer = NULL; m_dwTotalBufferSize = 0; m_dwSize_Sent = 0; m_bIOPending = FALSE; } ~SXClientBuffer() { delete [] m_szBuffer; } void DeleteBuffer() { if (m_szBuffer != NULL) delete [] m_szBuffer; m_szBuffer = NULL; m_dwSize = 0; } void CreateBuffer(int buffersize) { if (m_szBuffer == NULL) { m_szBuffer = new BYTE[buffersize]; m_dwTotalBufferSize = buffersize; m_bIOPending = FALSE; } } OVERLAPPED_BASE m_Overlapped; //overlapped DWORD m_dwTotalBufferSize; DWORD m_dwSize; //current size of buffer filled DWORD m_dwSize_Sent; BOOL m_bIOPending; BYTE* m_szBuffer; }; /**************************************************************************************** struct SIOCPPacketHeader union _header wID[0] : Msg Number (verifications) wID[1] : Msg Count; dwID : Unique ID of The message total of 256 messages for uses */ #define PACKET_HEADER (0) #define PACKET_COUNT (1) union _header { WORD wID[2]; DWORD dwID; }; /**************************************************************************************** struct CIOCPPacket COMMENTS : ±âº» Packet ÀÇ ¸ðÇü (½Ã¾ß°¡ ÇÊ¿ä ¾øÀ½ º» ¼¹ö¿¡¼ »ç¿ëÇÏ´Â ¸ðµç ¸Þ¼¼Áö´Â SIOCPPacket À» »ó¼Ó ¹Þ¾Æ¾ß ÇÑ´Ù */ struct SIOCPPacket { _header m_Header; DWORD m_dwSeq; }; struct SReadQueueBuffer_Header { UINT m_iClient; DWORD m_dwSize; }; struct SReadQueueBuffer { UINT m_iClient; BYTE* m_szBuffer; //ÃÖ´ë 4096¹ÙÀÌÆ® }; class CXReadQueue { public: CXReadQueue(); ~CXReadQueue(); BOOL InQueue (BYTE* szBuffer,DWORD dwSize,UINT iClient,DWORD currenttime = 0,BOOL bSeq = TRUE); SReadQueueBuffer_Header* OutQueue(BYTE** pBuffer); #ifdef DEBUG_MESSAGE_QUEUE DWORD m_dwReceivedSize; DWORD m_dwReceivedCount; #endif void EnterCritical(int client) { EnterCriticalSection(&m_csFlag); if (enter == 1) { char log[128]; sprintf_s(log,128,"%d depulicated Enter Critical(%d)\n",enter,client); //* OutputDebugString(log); } enter=1; } void LeaveCritical() { enter=0; LeaveCriticalSection(&m_csFlag);} CRITICAL_SECTION m_csFlag; protected: ::ofstream m_log; // read queue over log int enter; int enter2; DWORD m_dwCurrentReadAds; //current read pos DWORD m_dwCurrentWriteAds; //current wirte pos DWORD m_dwCurrentMsgCnt; //current msg count DWORD m_dwQueueSize; //current queue size (in byte) DWORD m_dwInitQueueSize; //total queue size DWORD m_dwQueueCCrUsing; //ends pointer (currently using current size) BYTE* m_pReadBuffer; //the buffer }; /**************************************************************************************** class CSClient */ #define CLIENT_COOL_TIME 5000 //socket cool time (not acceptable in cool time) class CXClient { public: CXClient(); //construction ~CXClient(); bool Init(int buffersize,int WritebufferSize); //init buffers void Close(int closenumber); //close socket BOOL Read(WORD wSize = MAX_ONETIME_RECEIVE_BUFFER); //set read in queue SOCKET GetSocket() {return m_Socket;} UINT GetClientNumber() {return m_iClient;} void SetClientNumber(UINT number) {m_iClient = number;} void SetSocket(SOCKET socket) {m_Socket = socket;} void SetConnectFlag(BOOL bConn) {m_bConnected = bConn;} BOOL IsConnected() {return m_bConnected;} //write and read operation**************************************************************** int Write(BYTE* szBuffer,DWORD dwSize,BOOL bExtra = FALSE); //write in queue void WriteSocket(); //write into IOCPs void WriteFinish(int sent); //write finished CRITICAL_SECTION m_csSWriteflag; void EnterWriteCS() {EnterCriticalSection(&m_csSWriteflag);} void LeaveWriteCS() {LeaveCriticalSection(&m_csSWriteflag);} SXClientBuffer* m_XReceiveBuffer; //receive buffer SXClientBuffer* m_XSendBuffer; //send buffer public: WORD m_wClientType; DWORD m_dwCoolTime; DWORD m_dwLastReceviedCount; //latency receive count DWORD m_dwLastReceivedTime; //latency char m_szPeerName[25]; #ifdef IOCP_MSG_SEQ UINT m_iRecvSeq; //sequence check UINT m_iSendSeq; #endif DWORD GetInitCnt() {return m_dwInitCnt;} int m_iFakeClient; //real sock num bool m_bFakeConnect; //real sock connected protected: SOCKET m_Socket; //socket UINT m_iClient; //Current Client array number BOOL m_bConnected; BOOL m_bCencelIO; long m_lPort; DWORD m_dwInitCnt; }; struct _SocInfo { BOOL bListen; int nIndex; char szTitle[25]; char szLocalIP[25]; char szIP[25]; int nPort; int nRecvSockBuffer; int nSendSockBuffer; int nReadQueueBuffer; int nSendQueueBuffer; }; #define FILE_CONNECT "connect.txt" class CIOCPNet; class CMultiToken { public: CMultiToken(){} ~CMultiToken(); BOOL Connect(CIOCPNet* pNet); void KeepAlive(); int DisConnect(int nClient); void SendReady(int iClient,int nServer,BOOL bSend = FALSE); BOOL Analize_ConnectData(); virtual void OnConnected(int /*iClient*/, int /*nServer*/) {} virtual void OnDisConnected(int /*iClient*/, int /*nServer*/) {} void Connected(int iClient, int nServer); void DisConnected(int iClient, int nServer); int GetServerNum() {return m_nServer;} int GetTotalServerCount() {return m_nSocInfoCount;} //CXCLIENT ¼ø¼ /* Listen SocInfo 1¹øºÎÅÍ ¿¡ µû¶ó 1ºÎÅÍ ½ÃÀÛÇÑ´Ù Listen SocInfo ÈĺÎÅÍ Connect ¼ø¼¿¡ µû¶ó 1ºÎÅÍ ½ÃÀÛÇÑ´Ù Listen SocInfo 0 Àº À¯Àú¿ëÀÓÀ¸·Î BRAVO_MAX_MULTI_SERVER ºÎÅÍ ½ÃÀÛÇÑ´Ù */ _SocInfo m_SocInfo[SOCKET_MAX_LISTEN]; int m_nConnectSocketCount; int m_nListenSocketCount; int m_nSocInfoCount; int m_nFirstlistencount; int GetFirstConnet(); int m_nZoneservercount; int m_nGatewaycount; int m_nStartGateway; int m_nExceptLiveserver; char m_chCaptionName[20]; BOOL m_arrSockAlive[SOCKET_MAX_LISTEN]; void Stop() { DWORD dwExit = 5; TerminateThread(m_hThread,dwExit);} protected: CIOCPNet* m_pIOCPNet; HANDLE m_hThread; DWORD m_dwThreadID; int m_iConnCount; // int m_nServer; //³» ¼¹ö¹øÈ£ }; class CIOCPToken { public: CIOCPToken() {} ~CIOCPToken() {} void Connected(int iClient); void DisConnected(int iClient); protected: virtual void OnConnected(int /*iClient*/) {} virtual void OnDisconnected(int /*iClient*/) {} }; /* CIOCPNet Windows MMORPG server engine using Windows IOCPs */ class CIOCPNet { public: //const & dist CIOCPNet(); ~CIOCPNet(); bool Init(HWND hParents, CIOCPToken* pToken, CMultiToken* pMultiToken = NULL); bool StartUp(); BOOL Process(); BOOL Accept(); BOOL Accept(SOCKET listen,int nNum,int nRecvSockBuffer,int nSendSockBuffer, int nReadQueueBuffer,int nSendQueueBuffe); void CloseClient(int iClient); int Connect(char* szPeerName, long port,int nClient ,char* szLocalIP ,int SocReadBuffer,int SocWriteBuffer ,int ReadQueueBuffer,int SendQueueBuffer); DWORD GetMsgSize(_header Header,UINT iClient); void GetStatus(SYSTEM_INFO* info,int* iThreads,int* iClients) { *info = m_SysInfo; *iThreads = m_iThreads; *iClients = m_iClients; } BOOL InitListen(long port,WORD listen,char* LocalIP=NULL); int GetClientCount() {return m_iClients;} void GetLocalName(char* addr = NULL); // gr 6_28 CMultiToken* GetMultiToken() {return m_pMultiToken;} // ¿¬°áÇϰíÀÚ ÇÏ´Â ¼¹öÀÇ CMultiTokenÀÇ Æ÷ÀÎÅͰªÀ» °¡Áü BOOL SockOptionSet(SOCKET soc,int nNum,int nRecvSockBuffer,int nSendSockBuffer); protected: int m_iClients; //client counts SYSTEM_INFO m_SysInfo; int m_iThreads; // ÃÑ _xThreadÀÇ ¾²·¡µå¼ö¸¦ °¡Áü DWORD m_dwCurrentTime; CIOCPToken* m_pToken; // ¿¬°áÇϰíÀÚ ÇÏ´Â ¼¹öÀÇ CIOCPTokenÀÇ Æ÷ÀÎÅͰªÀ» °¡Áü CMultiToken* m_pMultiToken; // ¿¬°áÇϰíÀÚ ÇÏ´Â ¼¹öÀÇ CMultiTokenÀÇ Æ÷ÀÎÅͰªÀ» °¡Áü HWND m_hParents; // ´ÙÀÌ¾Ë·Î±× HWND HANDLE m_hThreads[IOCP_THREADS_PER_CPU]; // _xThreadÀÇ ¾²·¡µå¸¦ cpu °³¼ö * 2¸¦ ¸¸µë HANDLE m_hThreadAccept; HANDLE m_hIOCP; // iocpÇÚµé long m_nPort; SOCKET m_ListenSoc[SOCKET_MAX_LISTEN]; // Áö±ÝÀº 0À̸é Ŭ¶óÀÌ¾ðÆ®¿ë ¸®½¼¼ÒÄÏ 1ÀÌ¸é ¼¹ö¿ë ¸®½¼¼ÒÄÏ void AnalyizeMsg(UINT iClient,DWORD dwSize); BOOL m_bPause; BOOL m_bOperate; ::ofstream m_IOCPclosenumber; int GetEmptyClient(); public: void Stop(); void EnterCriticalListen(){EnterCriticalSection(&m_ListenFlag);} void LeaveCriticalListen(){LeaveCriticalSection(&m_ListenFlag);} void EnterCriticalSListen(){EnterCriticalSection(&m_ListenFlag_Server);} void LeaveCriticalSListen(){LeaveCriticalSection(&m_ListenFlag_Server);} CRITICAL_SECTION m_ListenFlag; CRITICAL_SECTION m_ListenFlag_Server; }; extern CIOCPNet g_IOCPNet; extern CXReadQueue g_XReadQueue; extern CXClient g_ClientArray[IOCP_MAX_CLIENT_ACCPET]; extern DWORD g_arydwMsgSize[IOCP_MAX_CLIENT_MESSAGES]; extern DWORD g_arydwMsgSize_fromClient[IOCP_MAX_CLIENT_MESSAGES]; extern ::ofstream g_closenumber; extern void g_SetMsgSize(); extern void g_SetMsgSize_fromClient(); #endif