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