#if !defined(__MUGSOCS__) #define __MUGSOCS__ #define CSOC_SERVER_ID ((UINT)INT_MIN) #define CSOC_CLIENT_ID ((UINT)0) #define CSOC_LISTEN_ID ((UINT)-1) #if !defined(STATIC_FDARRAY_MAX) #define STATIC_FDARRAY_MAX 4 #endif // !defined(STATIC_FDARRAY_MAX) #if STATIC_FDARRAY_MAX < 0 #error must : STATIC_FDARRAY_MAX >= 0 #endif #if defined(SR_ASSERT) #ifdef ASSERT #undef ASSERT #endif // ASSERT #define ASSERT SR_ASSERT #endif // SR_ASSERT #ifndef NULL_CLASS_DEFINED #define NULL_CLASS_DEFINED class CNullClass {}; #endif #if !defined(SOCBase_Class) #define SOCBase_Class CNullClass #endif // !defined(SOCBase_Class) extern char SERVERID[]; #ifdef WIN32 #define ioctl(a,b,c) ioctlsocket(a,b,c) #endif //#define CMD_TYPEBREAKER 128 #ifndef MAX_PACKET #define MAX_PACKET 2048 #endif // !MAX_PACKET #ifndef MAX_FTPBUF #define MAX_FTPBUF 1024 // MAX_FTPBUF´Â MAX_PACKETº¸´Ù ¹Ýµå½Ã ÀÛ¾Æ¾ß ÇÑ´Ù? // 9+size==sizeof(bCmd) + sizeof(FTID) + sizeof(size) + size #endif // !MAX_FTPBUF // #define NO_PDCD - define PDCD for - no check PACKET_DUMP_CHECK_DISASSEMBLE - be very cautious!!! // #define NO_PDCA - define PDCA for - no check PACKET_DUMP_CHECK_ASSEMBLE - be very cautious??? #ifndef MY_LINGER_TIME #define MY_LINGER_TIME 250 #endif // !MY_LINGER_TIME #ifndef RCV_MAX #define RCV_MAX 10240 #endif // !RCV_MAX #ifndef SND_MAX #define SND_MAX 10240 #endif // !SND_MAX #if (SND_MAX < MAX_PACKET) || (RCV_MAX < MAX_PACKET) #error Both(SND_MAX & RCV_MAX) >= MAX_PACKET #endif #ifdef WIN32 #if !defined(NO_USE_OVRIO) #define USE_OVRIO #endif // !defined(NO_USE_OVRIO) #else // !WIN32 #undef USE_OVRIO #endif // WIN32 //#undef USE_OVRIO #define PUSHFLOAT(f) (*(DWORD*)&(f)) enum EException { EEXCP_NoError, // local side... EEXCP_TooLowVersion, EEXCP_Unknown, EEXCP_ConnectionTimeOut, EEXCP_ConnectionFailure, EEXCP_SendBufferOverflow, EEXCP_VersionError, // fatal socket error... EEXCP_WSAENETDOWN, EEXCP_WSANO_RECOVERY, EEXCP_WSAENETRESET, EEXCP_WSAECONNRESET, EEXCP_WSAECONNABORTED, EEXCP_WSAEADDRINUSE, EEXCP_WSAETIMEDOUT, EEXCP_WSAEHOSTUNREACH, EEXCP_WSAEACCES, // internal error EEXCP_WSANOTINITIALISED, EEXCP_WSAEFAULT, EEXCP_WSAENOTSOCK, EEXCP_WSAENOTCONN, EEXCP_WSAEOPNOTSUPP, EEXCP_WSAEINVAL, EEXCP_DupCreation, }; #if !defined(STRF_MAX_PARAMS) #define STRF_MAX_PARAMS 7 // should be 3 or 7 #endif #if !((STRF_MAX_PARAMS==3) || (STRF_MAX_PARAMS==7)) #error STRF_MAX_PARAMS size must be 3 or 7... #endif const char* SkipWord(const char* pcsz); const char* SkipWhite(const char* pcsz); const char* SkipWhiteReverse(const char* pcsz); BOOL IsControlExist(const char* pcsz); BOOL IsAllDigit(const char* pcsz); BOOL CheckStringOK(const char* pcsz, int nMin, int nMax); BOOL CheckNumberOK(const char* pcsz, int nMin, int nMax); BOOL IsInvalidCharsExist(const char* pcsz, const char* pcszInvalidChars); char* cmd_GetString(char*& psz, int nQuoteType = 0); int cmd_GetNumber(char*& psz, int& nNumber, int nMin = 0, int nMax = 65536); #ifdef WIN32 #pragma pack(push, 1) #endif // WIN32 DECLARE_TARRAYREF(CTEXTFmt); class CTEXTFmt : public CStr { public: union { struct { WORD m_wFmt; WORD m_wTX; } m_DW; DWORD m_dw; }; char m_caParamType[STRF_MAX_PARAMS + 1]; public: CTEXTFmt(const char* pcszFormat = NULL); }; #ifdef WIN32 #pragma pack(pop) #endif // WIN32 class CTEXTFmtArray : public TARRAYREF(CTEXTFmt) { public: class CAtoms : public TARRAYREF(CStr) { public: CStr m_strTitle; public: CAtoms(const char* pcsz) : m_strTitle(pcsz) { SetGrowBy(10); } }; TARRAYPTR(CAtoms*) m_paAtoms; public: CTEXTFmtArray(); virtual ~CTEXTFmtArray(); int LoadFmts(const char* pcszFile, const char* pcszSignature, BOOL bCheckACP = FALSE); CTEXTFmt& FindTEXTFmt(WORD wFmt) const; CAtoms* FindAtoms(const char* pcsz) const; void Sort(); private: int ProcessOneLine(BYTE baLine[], const char* pcszSignature, int nSizeOld, int nSize); CTEXTFmt& FindOnLoad(WORD wFmt, int nSizeOld, int nSize) const; static void ProcessEscape(BYTE* pb); }; #define ESTRF_OK 0 // no error #define ESTRF_ERR (-1) // Login Error #define ESTRF_VERSIONERROR 10 #define ESTRF_RESTART_PROGRAM 11 #define ESTRF_TOOMANY_CONNECTIONS 12 #define ESTRF_INVALIDLOGININFO 13 // C_LOGN_INFO invalid id or password #define ESTRF_INVALIDLOGINNAME 14 // C_LOGN_INFO #define ESTRF_INVALIDPASSWORD 15 // C_LOGN_INFO, C_ROOM_JOIN #define ESTRF_ALREADYLOGIN 16 // C_LOGN_INFO #define ESTRF_SAMEUSEREXIST 17 // C_USER_INFO #define ESTRF_NOSUCHUSER 18 // C_USER_INFO #define ESTRF_NAME 19 // C_USER_INFO #define ESTRF_EMAIL 20 // C_USER_INFO #define ESTRF_DATEBORN 21 // C_USER_INFO #define ESTRF_HOMEPAGE 22 // C_USER_INFO // DB error #define ESTRF_DBCONNECTION 30 // C_LOGN_INFO #define ESTRF_DBOPEN 31 // C_LOGN_INFO #define ESTRF_DBRESTART 32 // C_LOGN_INFO #define ESTRF_DBACCESS 33 // C_LOGN_INFO // Room Error #define ESTRF_TOOMANYROOMS 40 // C_ROOM_MAKE #define ESTRF_SAMEROOMEXIST 41 // C_ROOM_MAKE #define ESTRF_NOSUCHROOM 42 // C_ROOM_JOIN #define ESTRF_ALREADYINROOM 43 // C_ROOM_JOIN #define ESTRF_NOOTHERUSERS_IN_ROOM 44 #define ESTRF_TOOMANYUSERS_IN_ROOM 45 // C_ROOM_JOIN #define ESTRF_INVALID_ROOMNAME 46 // C_ROOM_JOIN... #define ESTRF_INVALID_ROOMPASSWORD 47 // C_ROOM_JOIN... #define ESTRF_INVALID_MAX 48 // C_ROOM_MAKE #define ESTRF_ROOM_STAT 49 // C_ROOM_STAT // Plyr Error #define ESTRF_OWNERCOMMAND 50 #define ESTRF_KICKEDBYOWNER 51 #define ESTRF_BANISHIEDBYOWNER 52 #define ESTRF_YOUAREALREADYBANISHIED 53 #define ESTRF_NOSUCHUSERINROOM 54 #define ESTRF_NOOWNERCOMMAND_TO_USER_INANOTHERROOM 55 #define ESTRF_OWNER_CHANGED 56 #define ESTRF_OWNER_CHANGED_AUTO 57 #define ESTRF_PLYR_IS_THERE 58 #define ESTRF_PLYR_NOT_LOGGED 59 #define ESTRF_PLYR_IS_THERE_LONELY 60 #define ESTRF_NOP_ON_SELF 61 #define ESTRF_JOIN_ANYROOM 62 #define ESTRF_NO_INVITATION_TO_USER_IN_SAME_ROOM 63 #define ESTRF_INVITATION_CALLED 64 #define ESTRF_INVITATION_CALLED_BY_OTHER 65 #define ESTRF_INVITER_LOGGEDOUT 66 #define ESTRF_INVITER_MOVED_ROOM 67 #define ESTRF_INVITATION_CHECK_ERROR 68 #define ESTRF_INVITITATION_ABORTED 69 #define ESTRF_INVITATION_DENIED 70 #define ESTRF_USER_BANISHIED 71 #define ESTRF_USER_KICKED 72 #define ESTRF_EX_ON 73 #define ESTRF_EX_OFF 74 #define ESTRF_YOUARE_SQUELDED_BY 75 #define ESTRF_USER_IS_NOT_RESPONDING 76 #define ESTRF_ALREADY_SQUELED 77 #define ESTRF_XSQUELED 78 #define ESTRF_YOUARE_XSQUELED_BY 79 #define ESTRF_SQUELED 80 #define ESTRF_YOUARE_SQUELED_BY 81 #define ESTRF_ALREADY_XSQUELED 82 #define ESTRF_SQUEL_COUNT_DROP 83 #define ESTRF_USER_START 100 #define ESTRF_PASSWORDCHANGED 110 // ·Î±×ÀÎÇϰí ÀÖ´Â µ¿¾È¿¡ ÆÐ½º¿öµå°¡ ¹Ù²ñ void Randomize(); union UPacketValue { // CPU register specific WORD m_w; DWORD m_dw; float m_f; double m_dbl; SINT64 m_i64; }; #define UPKV(pbPacket) ((UPacketValue*)(pbPacket)) class CDAPacket : public SOCBase_Class { // PacketÀÇ ¾Õ ºÎºÐÀ» ó¸®ÇÏ°í ³­ µÞ ºÎºÐÀÇ °¡º¯ ÆÄ¶ó¹ÌÅÍ... public: BYTE m_bCmd; BYTE m_bReserved; WORD m_wLen; BYTE* m_pbPacket; public: virtual CSOC* IsSOC() const { return NULL; } DWORD Push() const; void Pop(DWORD dw); BYTE* GetData(int nSize); BYTE* __cdecl Disassemble(const char* pcszFormat, ...); BYTE* __cdecl vDisassemble(const char* pcszFormat, va_list ap); }; #define CSCODE_OK 0 #define CSCODE_ERR 0xff #define CSCODE_CREATE 0 #define CSCODE_ADDED CSCODE_CREATE #define CSCODE_INFO 2 #define CSCODE_CHANGE 3 #define CSCODE_CHANGED CSCODE_CHANGE #define CSCODE_DELETE 4 #define CSCODE_DELETED CSCODE_DELETE #define CSCODE_WHERE 5 #define CSCODE_SAY 6 #define CSCODE_INVITE 7 #define CSCODE_INVITE_RESULT 8 #define CSCODE_TO 9 #define CSCODE_SQUEL 10 #define CSCODE_XSQUEL 11 #define CSCODE_EX 12 // dummy user... #define CSCODE_KICK 13 // C_PLYR_ACTN... #define CSCODE_BANISH 14 // C_PLYR_ACTN... #define CSCODE_CHOWNER 15 // C_PLYR_ACTN... #define CSCODE_TITLE 20 #define CSCODE_PASSWORD 21 #define CSCODE_MAX 23 #define CSCODE_START 0xfa #define CSCODE_MORE 0xfb #define CSCODE_STOP 0xfc #define S_PROG_INFO 200 #define C_PROG_INFO 200 // D - dwVersion #define S_LOGN_INFO 210 #define C_LOGN_INFO 210 // s - ID, s - Password #define S_LOGN_RSLT 211 // b - code(CSCODE_OK - ok or error code) #define C_USER_INFO 215 // b - code(CSCODE_CREATE/CSCODE_INFO/CSCODE_CHANGE/CSCODE_DELETE), s - ID, s - Password... #define S_USER_RSLT 215 // b - code(same w/ C_USER_INFO or CSCODE_ERR_...) if (code == CSCODE_INFO) additional user infos... #define S_PLYR_INFO 220 // b - code(CSCODE_ADDED/CSCODE_CHANGED/CSCODE_DELETED/CSCODE_START/CSCODE_STOP), s - name, ... #define C_PLYR_INFO 220 // b - code(CSCODE_NEXT/CSCODE_START/CSCODE_STOP) #define C_PLYR_STAT 221 // s - name #define S_PLYR_STAT 221 // b - code(CSCODE_OK - ok or error code) #define C_PLYR_ACTN 222 // b - code(CSCODE_INFO, CSCODE_KICK, CSCODE_BANISH), s - name, ... #define S_PLYR_ACTN 222 // b - code(CSCODE_KICK) #define S_SRVR_INFO 225 // b - code(CSCODE_ADDED/CSCODE_CHANGED/CSCODE_DELETED/CSCODE_START/CSCODE_STOP), d - number, s - name, ... #define C_SRVR_INFO 225 // b - code(CSCODE_NEXT/CSCODE_START/CSCODE_STOP) #define C_SRVR_STAT 226 // d - name #define S_SRVR_STAT 226 // b - code(CSCODE_OK - ok or error code) #define S_ROOM_INFO 230 // b - code(CSCODE_ADDED/CSCODE_CHANGED/CSCODE_DELETED/CSCODE_START/CSCODE_STOP), d - number, s - name, b - Password exist, w - user count... #define C_ROOM_INFO 230 // b - code(CSCODE_NEXT/CSCODE_START/CSCODE_STOP) #define C_ROOM_STAT 231 // room number #define S_ROOM_STAT 231 // b - code(CSCODE_OK - ok or error code) #define C_ROOM_MAKE 232 // s - name, s - password #define C_ROOM_JOIN 233 // d - number(RoomÀ» ¶°³ª´Â °ÍÀº -1), s - password #define S_ROOM_JOIN 233 // C_ROOM_MAKE/C_ROOM_JOINÀÇ °á°ú... // b - code(CSCODE_OK or error code), d - number #define C_ROOM_UPDS 234 // CSCODE_... + @ #define S_GAME_INFO 235 // b - code(CSCODE_ADDED/CSCODE_CHANGED/CSCODE_DELETED/CSCODE_START/CSCODE_STOP), d - number, s - name, ... #define C_GAME_INFO 235 // b - code(CSCODE_NEXT/CSCODE_START/CSCODE_STOP) #define C_GAME_STAT 236 // d - name #define S_GAME_STAT 236 // b - code(CSCODE_OK - ok or error code) #define C_GAME_RSLT 237 // same server/client command... #define X_TEXT 250 // %s{Sender/Receiver ID}%s{notify string}%W{TX_...} #define X_TEXTFMT 251 // %W{Format}%s{ParamFormat}[{params0}[{params2}[...]]] #define C_FTP 253 //... see ftp.txt #define S_FTP 254 //... see ftp.txt #define X_KEEPALIVE 255 // no parameters, should be ignored... #define TX_SYSTEM 0 // ½Ã½ºÅÛ ¸Þ½ÃÁö... #define TX_NORMAL 1 // ÀÏ¹Ý Ã¤ÆÃ ÅØ½ºÆ® #define TX_WARNING 2 // °æ°í #define TX_ERROR 3 // ¿À·ù #define TX_FATAL 4 // Ä¡¸íÀûÀÎ ¿À·ù #define TX_INFO 5 // »ç¿ëÀÚ Á¤º¸ µîÀÇ Information Result... #define TX_SAY 6 // ±Ó¼Ó¸» #define TX_LOCAL 7 // local echo.... #define TX_UNKNOWN 0xffff // unknown... typedef long (*PFN_TimerProc)(CTimerEvent& Timer); class CSOCListen; class CSOCClient; typedef CSOCClient* (*PFN_CreateSOCClient)(const CSOCListen& SOCListen, DWORD dwCSCParam1, DWORD dwCSCParam2); #ifdef WIN32 #pragma pack(push, 1) #endif // WIN32 class CTimerEvent { friend class CTimerPool; public: PFN_TimerProc m_pfnTimerProc; DWORD m_dwTime; void* m_pVoid; // no function params... int m_nParam; // not initialized... DWORD m_dwParam; // not initialized... protected: DWORD m_dwFrame; }; #ifdef WIN32 #pragma pack(pop) #endif // WIN32 #define CHK_TIMER_NOVOIDCHECK 0x8000 #define CHK_TIMER_ONCE 0x0001 class CTimerPool : public TARRAY(CTimerEvent) { private: int m_nReEnter; public: BOOL m_bDirty; protected: DWORD m_dwPrecision; DWORD m_dwLastTicks; private: DWORD m_dwFrame; public: CTimerPool(); public: DWORD GetPrecision() const { return m_dwPrecision; } void SetPrecision(DWORD dwPrecision) { m_dwPrecision = dwPrecision; } DWORD GetLastTicks() const { return m_dwLastTicks; } void SetLastTicks(DWORD dwLastTicks) { m_dwLastTicks = dwLastTicks; } public: void CheckTimers(); CTimerEvent& AddTimer(PFN_TimerProc pfnTimerProc, DWORD dwTime, void* pVoid); BOOL DelTimer(int nIndex); BOOL DelTimers(PFN_TimerProc pfnTimerProc, void* pVoid, UINT uFlags, int nFromIndex = 0); BOOL DelTimersAll() { return DelTimers((PFN_TimerProc)NULL, NULL, 0, 0); } int FindTimer(PFN_TimerProc pfnTimerProc, void* pVoid, UINT uFlags, int nFromIndex = 0); }; union UFmtParam { // CPU register specific BYTE m_b; // 'B' unsigned char m_c; // 'b' WORD m_w; // 'W' short m_s; // 'w' int m_n; // 'n' long m_l; // 'd' DWORD m_dw; // 'D' float m_f; double m_F; char* m_psz; // 's' or 'S' - don't mix... SINT64 m_i64; // '6' - 64 bit integer... // 'x' - binary data, wLen + Data // 'X' - mainly for Assemble, sub-packet copy... no info for disassemble // '!' - CPacketDumper* }; class CPacketDumper { public: public: CPacketDumper() {} virtual ~CPacketDumper() {} virtual BYTE* Disassemble(BYTE* pbPacket, BYTE* pbPacketEnd) = 0; virtual BYTE* Assemble(BYTE* pbPacket, BYTE* pbPacketEnd) = 0; }; #ifdef WIN32 #pragma pack(push, 1) #endif // WIN32 DECLARE_TARRAYREF(CPacket) class #ifdef WIN32 __declspec(novtable) #endif // WIN32 CPacket { friend class CSOCConnect; protected: CSOC* m_pSOC; private: // ÀÌ ¾ÈÀÇ ºí·°Àº ¹Ýµå½Ã ¿¬¼ÓÇØ¾ß ÇÑ´Ù... WORD m_wLen; BYTE m_ba[MAX_PACKET]; // public: CPacket(CSOC* pSOC); ~CPacket(); void Reset(); CSOC& GetSOC() const { ASSERT(this); return *m_pSOC; } const BYTE* GetPacketStart() const { return (const BYTE*)&m_wLen; } int GetLength() const { return m_wLen; } void SetLength(int nLen) { m_wLen = (WORD)(short)nLen; } BYTE* GetBuffer() const { return (BYTE*)&m_ba[0]; } int GetTotalLength() const { return sizeof(WORD) + m_wLen; } BYTE* GetLastPtr() const { return (BYTE*)&m_ba[m_wLen]; } BYTE* GetEndPtr() const { return (BYTE*)&m_ba[MAX_PACKET]; } void Prepare(int nSize) { m_wLen += (WORD)nSize; } BYTE* __cdecl Assemble(const char* pcszFormat, ...); BYTE* __cdecl vAssemble(const char* pcszFormat, va_list ap); BYTE* DisassembleParamsAndTextFmt(CSOCConnect& SOC, WORD wFmt, const char* pcszParamType, WORD& wTX); protected: void DropSOC(); BYTE* DoTextFmt(const char* pcszFormat, const UFmtParam aFPs[STRF_MAX_PARAMS], const char caParamType[/*STRF_MAX_PARAMS + 1*/]); }; #ifdef WIN32 #pragma pack(pop) #endif // WIN32 class CSockAddr : public sockaddr_in { public: CStr m_strTarget; public: CSockAddr(int nPort, const char* pcszAddr = NULL, short sFamily = AF_INET); CSockAddr(int nPort, u_long ulAddr = INADDR_ANY, short sFamily = AF_INET); public: sockaddr_in* GetSockAddrIn() { return this; } const char* GetTarget() const; u_long GetTargetAddr() const { return ntohl(sin_addr.s_addr); } void SetTarget(const char* pcszAddr); void SetTarget(u_long ulAddr); int GetPort() const; void SetPort(int nPort); }; const char* GetHostAddress(); typedef void (CSOC::*PF_PacketProcessor)(); #define PFPP_CallBase ((PF_PacketProcessor)0) // do not change this line... #define PFPP_Ignore CSOC::OnIgnore // why not? ((PF_PacketProcessor)1) #define MAX_PACKET_TYPE 256 // 1byte /**************** start of variable PACKET_MAP definitions... ****************/ struct _SPacketMap { public: _SPacketMap* m_pBaseMap; PF_PacketProcessor* m_pPFPP; public: PF_PacketProcessor TraceAndModifyBaseCall(BYTE bCmd, PF_PacketProcessor& refPFPP) const; }; #define PACKET_MAP(CLASSNAME) _CAutoStart##CLASSNAME #define PACKET_MAP_STATIC_INSTANCE(CLASSNAME) _g_AutoStart##CLASSNAME##Instance #define DECLARE_PACKET_MAP(thisClass) friend class PACKET_MAP(thisClass); protected: static PF_PacketProcessor m_aPFPP[MAX_PACKET_TYPE]; static _SPacketMap m_PacketMap; protected: virtual _SPacketMap* GetPacketMap() const; // start of BEGIN_PACKET_MAP_RAW, BEGIN_PACKET_MAP #define BEGIN_PACKET_MAP_RAW(thisClass, basePacketMap) PF_PacketProcessor thisClass::m_aPFPP[MAX_PACKET_TYPE] = { PFPP_CallBase, }; _SPacketMap thisClass::m_PacketMap = { basePacketMap, &thisClass::m_aPFPP[0] }; _SPacketMap* thisClass::GetPacketMap() const { return &thisClass::m_PacketMap; } class PACKET_MAP(thisClass) { public: PACKET_MAP(thisClass)() { #define BEGIN_PACKET_MAP(thisClass, baseClass) BEGIN_PACKET_MAP_RAW(thisClass, &baseClass::m_PacketMap) // end of BEGIN_PACKET_MAP_RAW, BEGIN_PACKET_MAP // start of PACKET_MAP_ENTRY_RAW, PACKET_MAP_ENTRY, PACKET_MAP_ENTRY_IGNORE #define PACKET_MAP_ENTRY_RAW(thisClass, bCmd, PFPP) ASSERT((0 <= bCmd) && (bCmd < MAX_PACKET_TYPE)); thisClass::m_aPFPP[bCmd] = (PF_PacketProcessor)&PFPP; #define PACKET_MAP_ENTRY(thisClass, bCmd, PFPP) PACKET_MAP_ENTRY_RAW(thisClass, bCmd, thisClass::PFPP) #define PACKET_MAP_ENTRY_IGNORE(thisClass, bCmd) PACKET_MAP_ENTRY_RAW(thisClass, bCmd, PFPP_Ignore) // end of PACKET_MAP_ENTRY & PACKET_MAP_ENTRY_IGNORE // start of END_PACKET_MAP #define END_PACKET_MAP(thisClass) } }; static PACKET_MAP(thisClass) PACKET_MAP_STATIC_INSTANCE(thisClass); // end of END_PACKET_MAP /**************** end of variable PACKET_MAP definitions... ****************/ class CFileTransfer : public TDBLNK(CFileTransfer*) { public: // ¼­¹ö·Î ºÎÅÍ ¹ÞÀº Á¤º¸... - ȤÀº Ŭ¶óÀÌ¾ðÆ®¿¡°Ô ÀüÇØÁÙ Á¤º¸... BOOL m_bClientSite; DWORD m_dwFTID; DWORD m_dwGUARD; CStr m_strFileNameRemote; DWORD m_dwTime; long m_lSize; UINT m_uMinBPS; UINT m_uMaxBPS; CStr m_strFileNameLocal; int m_nFile; long m_lPos; DWORD m_dwStartTime; public: CFileTransfer(DWORD dwFTID, DWORD dwGUARD, const char* pcszFileNameRemote, const char* pcszFileNameLocal); virtual ~CFileTransfer(); virtual BOOL Setup(DWORD& dwError); virtual BOOL Setup(DWORD dwTime, long lSize, DWORD& dwError); virtual int CheckReadPosition(long lPosition) const; int Close(); void Start(); }; class CFTPArray : TARRAY(CFileTransfer*) { public: public: CFTPArray(); virtual ~CFTPArray(); int Find(CFileTransfer* pFTP) const; CFileTransfer* CutIfExist(CFileTransfer* pFTP); }; #ifdef USE_OVRIO DECLARE_TARRAYREF(COVRIO); #ifdef WIN32 #pragma pack(push, 1) #endif // WIN32 class #ifdef WIN32 __declspec(novtable) #endif // WIN32 COVRIO : public TDoubleLinkRef { public: CSOC* m_pSOC; int m_nSize; BYTE m_ba[/*m_nSize*/]; public: COVRIO(); ~COVRIO(); DECLARE_STATIC_CONSTRUCTION(COVRIO); }; #ifdef WIN32 #pragma pack(pop) #endif // WIN32 COVRIO* newCOVRIO(CSOC* pSOC, const BYTE* pb, int nSize); void deleteCOVRIO(COVRIO* pOVRIO); void CALLBACK OVRIO_Completion(DWORD dwError, DWORD cbTransferred, LPWSAOVERLAPPED lpOverlapped, DWORD dwFlags); #endif // USE_OVRIO #define SOCNEXT_EXCCLIENT 0x0001 #define SOCNEXT_EXCSERVER 0x0002 #define SOCNEXT_EXCLISTEN 0x0004 #define SOCNEXT_EXCINVALID 0x0010 #define SOCNEXT_EXCDROPPING 0x0020 #define SOCNEXT_EXCCONNECTTING 0x0080 // CSOCServer Only... #define SOCNEXT_CHECKPROC 0x4000 #define SOCNEXT_REVERSE 0x8000 #define SOCNEXT_DEFAULT (SOCNEXT_EXCINVALID|SOCNEXT_EXCDROPPING|SOCNEXT_EXCLISTEN|SOCNEXT_EXCCONNECTTING) class CSOC : public CDAPacket { friend class CSOCManager; DECLARE_PACKET_MAP(CSOC) protected: int m_nLockCount; SOCKET m_hSocket; int m_nState; BOOL m_bSendLoop; CSOCManager* m_pSOCManager; CSockAddr m_Addr; // time - last Rcv/Snd DWORD m_dwKARcvTicks; DWORD m_dwKASndTicks; // time out to Drop... DWORD m_dwKARcvTimeOut; #ifdef WIN32 // º¸Åë Login°úÁ¤¿¡ ¾²ÀÌ´Â À©µµ¿ì ÇÚµé HWND m_hWndOwner; #endif // WIN32 // º¸Åë ±Û·Î¹ú º¯¼ö·Î ¾²ÀÌ´Â ¼ÒÄÏÆ÷ÀÎÅÍ¿¡ ´ëÇÑ ÀÚµ¿ NULL AssignÀ» À§ÇÏ¿© PSOC* m_ppSOC; // ¼ÒÄÏÀ» ±¸ºÐÇϱâ À§ÇÏ¿© »ç¿ëÀÚ ÇÁ·Î±×·¥¿¡¼­ ¾²ÀÌ´Â ¾ÆÀ̵ð // ÁÖ·Î ¼­¹öÀÇ °æ¿ì¿¡´Â Ŭ¶óÀÌ¾ðÆ®°¡ Á¢¼ÓÇÒ ¶§¸¶´Ù °íÀ¯ ¾ÆÀ̵𸦠ºÎ¿©ÇÏ¿© »ç¿ë // ÇϳªÀÇ Client°¡ ´Ù¼öÀÇ ¼­¹ö¿¡ Á¢¼ÓÇÒ ¶§(ÁÖ·Î StarÇü) °¢°¢ÀÇ Á¢¼ÓÀ» ±¸ºÐÇÒ ¶§ »ç¿ë // Ŭ¶óÀÌ¾ðÆ®°¡ ÇϳªÀÇ ¼­¹ö¿¡¸¸ Á¢¼ÓÇÏ´Â °æ¿ì Ŭ¶óÀÌ¾ðÆ®°¡ ¼­¹ö¿¡ Á¢¼Ó ÁßÀÎÁö ȤÀº Á¢¼ÓÇß´ÂÁö¸¦ ÆÇ´ÜÇÒ ¶§ // CSOCManager::FindSOC(CSOC_SERVER_ID==default)->GetConnectionState()¸¦ »ç¿ë. // limits.h¸¦ includeÇØ¾ßÇÔ. // CSOC»ý¼º½ÃÀÇ ±âº»°ª: CSOCServer == CSOC_SERVER_ID(=INT_MIN), CSOCClient == CSOC_CLIENT_ID(=0), CSOCListen == CSOC_LISTEN_ID(=-1) union { int m_nID; UINT m_uID; void* m_pvID; } m_ID; protected: DWORD m_dwDroppingTicks; public: TDeQueueFixed m_aRcv; #ifdef USE_OVRIO COVRIO* m_pOVRIOStart; #else // !USE_OVRIO TDeQueueFixed m_aSnd; #endif // USE_OVRIO protected: // don't use this - use get/set functions only... union { struct { DWORD m_xAllowAccept: 1; // CSOCListen Only... DWORD m_xUseSelect: 1; // Use select() for Acception Check... DWORD m_xAutoDelete: 1; DWORD m_xAdded: 1; DWORD m_xIsConnected: 1; DWORD m_xIsConnecting: 1; DWORD m_xDoDelSocket: 1; DWORD m_xIsDropping: 1; DWORD m_xIsSetupFailure: 1; DWORD m_xGracefulLocal: 1; DWORD m_xErrSEND: 1; DWORD m_xErrRECEIVE: 1; DWORD m_xGracefulRemote: 1; DWORD m_xAbortyLocal: 1; DWORD m_xAbortyRemote: 1; DWORD m_xLoginStarted: 1; // »ç¿ëÀÚ°¡ Á÷Á¢ °ªÀ» SettingÇØ¾ß ÇÑ´Ù. DWORD m_xLoginOK: 1; // »ç¿ëÀÚ°¡ Á÷Á¢ °ªÀ» SettingÇØ¾ß ÇÑ´Ù. } m_DW; DWORD m_dwVarFlags; }; public: CSOC(); virtual ~CSOC(); void Reset(); public: operator SOCKET () const { return m_hSocket; } SOCKET GetSocket() const { return m_hSocket; } BOOL IsValidSafe() const { return this && (m_hSocket != INVALID_SOCKET); } BOOL IsValid() const { return m_hSocket != INVALID_SOCKET; } int GetID() const { return m_ID.m_nID; } void SetID(int nID) { m_ID.m_nID = nID; } void Lock() { m_nLockCount++; } void Unlock() { ASSERT(m_nLockCount > 0); m_nLockCount--; } int GetLockCount() const { return m_nLockCount; } BOOL IsConnecting() const { return m_DW.m_xIsConnecting; } BOOL IsConnected() const { return m_DW.m_xIsConnected; } BOOL IsDroppingState() const { return m_DW.m_xIsDropping; } CSockAddr& GetSockAddr() const { return *(CSockAddr*)&m_Addr; } void SetRcvTimeOut(DWORD dwTimeOut) { m_dwKARcvTimeOut = dwTimeOut; } #ifdef WIN32 HWND GetOwnerHWND() const { return m_hWndOwner; } void SetOwnerHWND(HWND hWndOwner) { m_hWndOwner = hWndOwner; } #endif // WIN32 PSOC* GetSOCPP() const { return m_ppSOC; } void SetSOCPP(PSOC* ppSOC) { if (this) m_ppSOC = ppSOC; } BOOL GetLoginStarted() const { return m_DW.m_xLoginStarted; } void SetLoginStarted(BOOL bLoginStarted) { m_DW.m_xLoginStarted = !!bLoginStarted; } BOOL GetLoginOK() const { return m_DW.m_xLoginOK; } void SetLoginOK(BOOL bLoginOK) { m_DW.m_xLoginOK = !!bLoginOK; } BOOL GetUseSelect() const { return m_DW.m_xUseSelect; } void SetUseSelect(BOOL bUseSelect) { m_DW.m_xUseSelect = !!bUseSelect; } BOOL GetSendLoop() const { return m_bSendLoop; } void SetSendLoop(BOOL bSendLoop) { m_bSendLoop = bSendLoop; } const char* GetTarget() const { return m_Addr.m_strTarget; } void SetTarget(const char* pcszTarget) { m_Addr.SetTarget(pcszTarget); } void SetTarget(u_long ulAddr) { m_Addr.SetTarget(ulAddr); } int GetPort() const { return m_Addr.GetPort(); } void SetPort(int nPort) { m_Addr.SetPort(nPort); } BOOL GetAutoDelete() const { return m_DW.m_xAutoDelete; } void SetAutoDelete(BOOL bAutoDelete) { m_DW.m_xAutoDelete = !!bAutoDelete; } int GetState() const { return m_nState; } void SetState(int nState) { m_nState = nState; } CSOCManager& GetSOCManager() const { return *m_pSOCManager; } void SetSOCManager(CSOCManager* pSOCManager) { ASSERT(!m_pSOCManager || !pSOCManager); m_pSOCManager = pSOCManager; } BOOL IsAdded() const { return m_DW.m_xAdded; } void SetAdded(BOOL bAdded) { m_DW.m_xAdded = !!bAdded; } CFileTransfer* FindFTP(DWORD dwFTID) const; CFileTransfer* FindFTP(const char* pcszFileNameRemote) const; public: int GetSignatureFromPort(int nPort) const; int GetConnectionState() const; void Drop(); public: BOOL DoSend(const BYTE* pbBuf, int nSize); BOOL DoSendCmdWOP(BYTE bCmd); void DoSendLoginOK(); void DoSendLoginError(); void DoSendLoginError(WORD wErrFMT); BOOL DoSend(const CPacket& Packet); BOOL DoSendX(BYTE bCmd, const void* pData, int nLen); BOOL __cdecl DoSendX(const char* pcszFormat, ...); BOOL DoSendText(BYTE bCmd, const char* pcsz); BOOL DoSendText(const char* pcszID, const char* pcsz, WORD wTX = TX_NORMAL); BOOL __cdecl DoSendFmt(WORD wFmt, const char* pcszParamType = NULL, ...); BOOL vDoSendFmt(WORD wFmt, const char* pcszParamType, va_list ap); public: virtual CSOC* IsSOC() const { return (CSOC*)this; } virtual BOOL CheckProc(DWORD dwParam) { return TRUE; } virtual DWORD GetSendTimeOut() const { return 5 * 1000; } virtual BOOL IsListenSocket() const { return FALSE; } virtual BOOL IsClientSocket() const { return FALSE; } virtual BOOL IsServerSocket() const { return FALSE; } virtual UINT GetType() const { return 0; } virtual UINT GetType3() const = 0; virtual const CTEXTFmtArray& GetTEXTFmtArray(); virtual const CTEXTFmt& GetTEXTFmt(WORD wFmt); virtual BOOL DoProcessPacket(); virtual void OnOpen(); virtual BOOL OnSetupSocket(); virtual void OnAddSocket(); virtual void OnDropping(); virtual void OnDelSocket(); virtual void OnShutdown(); virtual void OnClose(); virtual void OnDelete(); virtual void OnSendKeepAlive(); #if !defined(USE_OVRIO) virtual BOOL OnOverflow(int nSizeReq, int nRetry, DWORD dwTimeBegin); #endif // !defined(USE_OVRIO) public: // packet handler map void OnIgnore(); void OnKeepAlive(); #ifdef USE_OVRIO COVRIO* newCOVRIO(const BYTE* pb, int nSize); void deleteCOVRIO(COVRIO* pOVRIO); void OnOVRIO_Completion(DWORD dwError, DWORD cbTransferred, COVRIO* pOVRIO, DWORD dwFlags); #endif // USE_OVRIO int aSnd_GetDataSize(); protected: BOOL IsSendPossible() const { return !(m_DW.m_xErrSEND || m_DW.m_xAbortyRemote || m_DW.m_xGracefulLocal); } BOOL IsReceivePossible() const { return !(m_DW.m_xErrRECEIVE || m_DW.m_xAbortyRemote || m_DW.m_xGracefulRemote); } BOOL DoClose(); void CheckAutoDelete(); void SetDroppingTicks(); BOOL CreateAndAttach(); void CallOnOpen(SOCKET soc); void CallOnDropping(); void CallOnShutdown(int nHow); void CallOnClose(); void CallOnDelete(); protected: void DoPacketProcessing(); BOOL OnReceive(); int DoReceive(BYTE* pbBuf, int nLen); int OnSend(); protected: void SendKeepAlive(); void ResetKeepAliveAll(); void ResetKeepAliveRcv(); void ResetKeepAliveSnd(); protected: EException GetExceptionCode(int nErrorCode); EException DoErrorReport(int nErrorCode, BOOL bDropIfErrorOccur = FALSE); EException DoExceptions(EException eException, BOOL bDropIfErrorOccur = FALSE); }; class CSOCListen : public CSOC { friend class CSOC; friend class CSOCManager; protected: PFN_CreateSOCClient m_pfnCSC; DWORD m_dwCSCParam1; DWORD m_dwCSCParam2; DWORD m_dwListenTime; DWORD m_dwLastCheck; public: CSOCListen(int nPort = 0, DWORD dwListenTime = 250); virtual ~CSOCListen(); DWORD GetListenTime() const { return m_dwListenTime; } void SetListenTime(DWORD dwListenTime) { m_dwListenTime = dwListenTime; } BOOL GetAllowAccept() const { return m_DW.m_xAllowAccept; } void SetAllowAccept(BOOL bAllowAccept) { m_DW.m_xAllowAccept = !!bAllowAccept; } void GetCSCParam(PFN_CreateSOCClient& pfnCSC, DWORD& dwCSCParam1, DWORD& dwCSCParam2) const; void SetCSCParam(PFN_CreateSOCClient pfnCSC, DWORD dwCSCParam1, DWORD dwCSCParam2); public: virtual BOOL IsListenSocket() const { return TRUE; } virtual UINT GetType3() const { return SOCNEXT_EXCLISTEN; } virtual BOOL BindAndListenSocket(); virtual void OnAcception(); virtual CSOCClient* OnNewClientSocket() const; virtual BOOL OnAddrAcceptionCheck(const sockaddr_in& Addr) { return TRUE; } virtual BOOL DoProcessPacket() { m_aRcv.FreeAll(); return FALSE; } }; class CSOCConnect : public CSOC { friend class CSOC; friend class CSOCManager; DECLARE_PACKET_MAP(CSOCConnect) protected: time_t m_tConnection; DWORD m_dwLingerTime; CFileTransfer* m_pFTPStart; public: CSOCConnect(DWORD dwLingerTime); virtual ~CSOCConnect(); public: time_t GetConnectionTime() const { return m_tConnection; } DWORD GetConnectionTicks() const; DWORD GetConnectionTimeString(CStr& strTime, BOOL bForceShowMin = FALSE, BOOL bForceShowHour = FALSE) const; void SetConnectionTime(); DWORD GetLingerTime() const { return m_dwLingerTime; } void SetLingerTime(DWORD dwLingerTime) { m_dwLingerTime = dwLingerTime; } public: BOOL DoFileTransfer(DWORD dwGUARD, const char* pcszFileNameRemote); CFileTransfer* FindFTP(DWORD dwFTID) const; CFileTransfer* FindFTP(const char* pcszFileNameRemote) const; void DoFTPCloseAllAsError(); public: virtual void DoTextDisplay(const char* pcszID, const char* pcszMsg, WORD wTX); public: // FTP virtual... virtual void OnFTPFileInfoNotify(CFileTransfer* pFTP); virtual void OnFTPError(CFileTransfer* pFTP, long lErrorCode); virtual const char* OnFTPDirectory(BOOL bClientSite) const; virtual const char* OnFTPFileNameValidation(const char* pcszFileName) const; virtual void OnFTPFileMap(DWORD dwGUARD, const char* pcszFileNameRemote, CStr& strFileNameLocal, BOOL bClientSite) const; virtual void OnFTPSrvrError(DWORD dwGUARD, const char* pcszFileNameRemote, DWORD dwError); virtual void OnFTPNotFound(DWORD dwFTID, BOOL bClientSite); virtual CFileTransfer* OnAllocFileTransfer(DWORD dwGUARD, const char* pcszFileNameRemote, DWORD& dwError); virtual CFileTransfer* OnAllocFileTransfer(DWORD dwFTID, DWORD dwGUARD, const char* pcszFileNameRemote, DWORD dwTime, long lSize, DWORD& dwError); virtual CFileTransfer* OnNewFileTransfer(DWORD dwFTID, DWORD dwGUARD, const char* pcszFileNameRemote, const char* pcszFileNameLocal); virtual void OnFreeFileTransfer(CFileTransfer* pFTP); virtual void OnFTPRead(CFileTransfer* pFTP, long lSize); virtual void OnFTPWrite(CFileTransfer* pFTP, long lPosition); virtual void OnFTPTerminate(CFileTransfer* pFTP); virtual BOOL DoFTPWrite(CFileTransfer* pFTP, const BYTE* pb, long lSize); virtual long DoFTPRead(CFileTransfer* pFTP, const BYTE* pb, long lSize); public: // packet handler map void OnText(); void OnTextFmt(); void OnFTP(); protected: BOOL CheckDroppingTicks(DWORD dwTicks); }; class CSOCClient : public CSOCConnect { friend class CSOC; friend class CSOCListen; friend class CSOCConnect; friend class CSOCServer; friend class CSOCManager; DECLARE_PACKET_MAP(CSOCClient) public: TARRAYREF(CStr) m_astrGroups; public: CSOCClient(DWORD dwLingerTime = MY_LINGER_TIME); virtual ~CSOCClient(); public: virtual BOOL IsClientSocket() const { return TRUE; } virtual UINT GetType3() const { return SOCNEXT_EXCCLIENT; } virtual BOOL OnCheckIDAndPassword(const char* pcszID, const char* pcszPW); virtual void OnAccept(); public: // packet handler map protected: void CallOnAccept(); }; class CSOCServer : public CSOCConnect { friend class CSOC; friend class CSOCListen; friend class CSOCConnect; friend class CSOCClient; friend class CSOCManager; DECLARE_PACKET_MAP(CSOCServer) public: CSOCServer(const char* pcszTarget = NULL, int nPort = 0, DWORD dwLingerTime = MY_LINGER_TIME); virtual ~CSOCServer(); public: void CallOnConnectionTimeOut(); // do not use the function, should be protected but... public: virtual BOOL IsServerSocket() const { return TRUE; } virtual UINT GetType3() const { return SOCNEXT_EXCSERVER; } virtual void OnConnect(); virtual void OnConnectionTimeOut(); public: // packet handler map protected: BOOL DoConnect(); void CallOnConnect(); }; class CSOCUDP { protected: CSockAddr m_Addr; SOCKET m_hSocket; int m_nPort; public: CSOCUDP(int nPort = 0); virtual ~CSOCUDP(); CSockAddr& GetSockAddr() const { return *(CSockAddr*)&m_Addr; } operator SOCKET () const { return m_hSocket; } SOCKET GetSocket() const { return m_hSocket; } BOOL IsValidSafe() const { return this && (m_hSocket != INVALID_SOCKET); } BOOL IsValid() const { return m_hSocket != INVALID_SOCKET; } int GetPort() const { return m_nPort; } UINT GetMAX_MSG_SIZE() const; BOOL CreateAndBind(int nPort = 0); void Drop(); BOOL IsReadable() const; BOOL IsWritable() const; int Send(const void* pBuffer, int nLen, DWORD dwAddr, int nPort); int Recv(void* pBuffer, int nLen, DWORD& dwAddr, int& nPort); int Send(const void* pBuffer, int nLen, const sockaddr_in& Addr); int Recv(void* pBuffer, int nLen, sockaddr_in& Addr); }; template class TSOCArray : public TARRAY(CSOCClass*) { public: public: int FindIndex(CSOCClass* pSOC) const { int nSize = GetSize(); CSOCClass** pp = &GetAt(nSize); while(nSize-- > 0) { if (*--pp == pSOC) break; } return nSize; } int DelIfExist(CSOCClass* pSOC) { int nIndex = FindIndex(pSOC); if (nIndex != -1) { Del(nIndex); } return nIndex; } }; #ifdef WIN32 #define XFD_ARRAY fd_set #else // !WIN32 struct XFD_ARRAY { public: int fd_count; SOCKET fd_array[FD_SETSIZE]; }; #endif // WIN32 class XFD_SET : protected XFD_ARRAY { private: #if !defined(WIN32) fd_set m_FD_SET; #endif // !defined(WIN32) public: XFD_SET(); XFD_SET(SOCKET soc); XFD_SET(const XFD_SET& that); int GetCount() const { return fd_count; } SOCKET* GetFDs() const { return (SOCKET*)&fd_array[0]; } void Assign(const XFD_SET& that); int FindIndexFromHandle(SOCKET soc) const; void ZERO(); BOOL ISSET(SOCKET soc); void SET(SOCKET soc); void CLR(SOCKET soc); void CLR_Index(int nIndex); XFD_ARRAY& GetFD_ARRAY() const; fd_set& GetFD_SET() const; int Select(int nType); #ifdef _DEBUG void CheckHandleMap() const; #endif // _DEBUG }; class CFDSet : protected XFD_SET { protected: PSOC m_paSOCs[FD_SETSIZE]; public: CFDSet(); virtual ~CFDSet(); public: CSOC* GetSOCFromHandle(SOCKET soc) const; int GetCount() const { return fd_count; } PSOC* GetStartOfSOCs() const { return (PSOC*)&m_paSOCs[0]; } PSOC FindSOC(SOCKET soc, int& nIndex) const; #ifdef _DEBUG void CheckHandleMap() const; #endif // _DEBUG void SET(const CSOC& SOC); void CLR(const CSOC& SOC); void CLR_Index(int nIndex); protected: BOOL AddSOC(CSOC& SOC); void DelSOC(CSOC& SOC); void DelSOCFromIndex(CSOC& SOC, int nIndex); }; class CDroppings : protected TSOCArray { friend class CSOCManager; public: public: void AddWithFlush(CSOC* pSOC); }; template class TFD_SET_Dynamic { private: int m_nLevel; XFD_SET* m_pFD_SET; XFD_SET m_aFD_SET[nFDArrayMAX]; TARRAYPTR2(XFD_SET*) m_paFD_SET; public: TFD_SET_Dynamic() { m_nLevel = 0; m_pFD_SET = NULL; m_paFD_SET.SetGrowBy(3); } ~TFD_SET_Dynamic() { ASSERT(m_nLevel == 0); } void Alloc() { if (m_nLevel < nFDArrayMAX) { m_pFD_SET = &m_aFD_SET[m_nLevel]; } else { XFD_SET* p = (XFD_SET*)malloc(sizeof(XFD_SET)); m_paFD_SET.Add() = p; m_pFD_SET = p; } m_nLevel++; } void Free() { ASSERT(m_nLevel > 0); #ifdef _DEBUG if (m_nLevel <= nFDArrayMAX) { ASSERT(m_paFD_SET.GetSize() == 0); } else { ASSERT(nFDArrayMAX + m_paFD_SET.GetSize() == m_nLevel); } #endif // _DEBUG if (--m_nLevel > 0) { if (m_nLevel < nFDArrayMAX) { m_pFD_SET = &m_aFD_SET[m_nLevel]; } else { int nIndex = m_nLevel - nFDArrayMAX; m_paFD_SET.Del(nIndex); if (--nIndex < 0) { m_pFD_SET = &m_aFD_SET[nFDArrayMAX - 1]; } else { m_pFD_SET = m_paFD_SET.At(nIndex); } } } else { ASSERT(m_nLevel == 0); m_pFD_SET = NULL; } } XFD_SET* GetFD_SET(const TSOCArray& aSOCs) const { ASSERT(m_pFD_SET && &aSOCs); int nSize = aSOCs.GetSize(); XFD_SET& fd = *m_pFD_SET; XFD_ARRAY& fda = fd.GetFD_ARRAY(); fda.fd_count = nSize; #if !defined(WIN32) fd_set& u = fd.GetFD_SET(); FD_ZERO(&u); #endif // !defined(WIN32) SOCKET* pSOCKET = &fda.fd_array[0]; CSOC** ppSOC = &aSOCs.GetAt(0); while(nSize-- > 0) { CSOC* pSOC = *ppSOC++; *pSOCKET++ = *pSOC; #if !defined(WIN32) SOCKET soc = *pSOC; FD_SET(soc, &u); #endif // !defined(WIN32) } return &fd; } XFD_SET* GetFD_SET(const XFD_SET& fd) const { ASSERT(m_pFD_SET && &fd); m_pFD_SET->Assign(fd); return m_pFD_SET; } }; class CSOCManager : public CFDSet { friend class CSOC; friend class CSOCListen; friend class CSOCConnect; friend class CSOCClient; friend class CSOCServer; private: TFD_SET_Dynamic m_FD_Dynamic; protected: int m_nStarted; // socsystem WORD m_wVersionRequested; #ifdef WIN32 WSADATA m_wsaData; #endif // WIN32 // socmanager int m_nDroppingSockets; TSOCArray m_paConnectings; CDroppings m_paDroppings; public: DWORD m_dwConnectTimeOut; CTimerPool m_aTimerPool; public: CSOCManager(DWORD dwConnectTimeOut = 20000); virtual ~CSOCManager(); public: BOOL IsStarted() const { return m_nStarted > 0; } DWORD GetConnectTimeOut() const { return m_dwConnectTimeOut; } void SetConnectTimeOut(DWORD dwConnectTimeOut) { m_dwConnectTimeOut = dwConnectTimeOut; } public: CSOCListen* GetListenSocket() const; CSOC* FindSOC(int nID = CSOC_SERVER_ID) const; CSOCServer* FindSOCServeLogin(int nID = CSOC_SERVER_ID) const; CSOC* GetNextSocket(UINT uType, UINT uMask, CSOC* pSOC, int& nIndex, DWORD dwParam = 0); BOOL DoListen(CSOCListen* pSOCListen, int nPort = 0); CSOCListen* DoListen(int nPort, PFN_CreateSOCClient pfnCSC, DWORD dwCSCParam1, DWORD dwCSCParam2); BOOL DoConnect(CSOCServer* pSOCServer, const char* pcszTarget = NULL, int nPort = 0); void DropAll(BOOL bWait = TRUE); EException OnExceptions(CSOC* pSOC, EException eException, BOOL bDropIfErrorOccur = FALSE); public: virtual BOOL Init(); virtual void Exit(); virtual BOOL Startup(); virtual void Shutdown(); virtual BOOL SetupInitialOption(); virtual BOOL InitSignal(); virtual void ExitSignal(); virtual void OnAddSocket(CSOC& SOC); virtual void OnDelSocket(CSOC& SOC); virtual void SingleStep(); virtual CSOCClient* OnNewClientSocket(const CSOCListen& SOCListen, DWORD dwCSCParam1, DWORD dwCSCParam2) const; protected: BOOL AddSocket(CSOC& SOC); void CallOnAddSocket(CSOC& SOC); void CallOnDelSocket(CSOC& SOC); void OnDrop(CSOC* pSOC); void DoConnecting(CSOCServer* pSOCServer, BOOL bConnecting); BOOL IsSafeToShutdown() const; protected: // in single step void CheckDropping(); void CheckFlush(); void CheckReading(); protected: EException DoErrorReport(CSOC* pSOC, int nErrorCode, BOOL bDropIfErrorOccur = FALSE); }; #endif // !defined(__MUGSOCS__)