MTCPSocket.h
00001 #ifndef MTCPSOCKET_H 00002 #define MTCPSOCKET_H 00003 00004 #pragma warning(disable:4786) 00005 #include <list> 00006 #include <vector> 00007 #include <deque> 00008 #include <algorithm> 00009 using namespace std; 00010 00011 #include <winsock2.h> 00012 #include <windows.h> 00013 #include <crtdbg.h> 00014 #include <stdio.h> 00015 #include <stdlib.h> 00016 #include <time.h> 00017 00018 #include "MSync.h" 00019 #include "MThread.h" 00020 #include "MPacket.h" 00021 #include "MCommand.h" 00022 #include "MTrafficLog.h" 00023 00024 00025 class MTCPSocket; 00026 class MServerSocket; 00027 class MClientSocket; 00028 00029 struct MTCPSendQueueItem 00030 { 00031 char* pPacket; 00032 DWORD dwPacketSize; 00033 }; 00034 00035 typedef list<MTCPSendQueueItem*> TCPSendList; 00036 typedef TCPSendList::iterator TCPSendListItor; 00037 00038 struct MSocketObj 00039 { 00040 SOCKET sock; 00041 HANDLE event; 00042 TCPSendList sendlist; 00043 }; 00044 00045 typedef list<MSocketObj*> SocketList; 00046 typedef SocketList::iterator SocketListItor; 00047 00048 enum SOCKET_ERROR_EVENT {eeGeneral, eeSend, eeReceive, eeConnect, eeDisconnect, eeAccept}; 00049 00050 // general callback 00051 typedef void(MSOCKETERRORCALLBACK)(void* pCallbackContext, SOCKET sock, SOCKET_ERROR_EVENT ErrorEvent, int &ErrorCode); 00052 // client callback 00053 typedef bool(MCLIENTRECVCALLBACK)(void* pCallbackContext, SOCKET socket, char* pPacket, DWORD dwSize); 00054 typedef bool(MCONNECTCALLBACK)(void* pCallbackContext, SOCKET sock); 00055 typedef bool(MDISCONNECTCALLBACK)(void* pCallbackContext, SOCKET sock); 00056 // server callback 00057 typedef bool(MSERVERRECVCALLBACK)(MSocketObj* pSocketObj, char* pPacket, DWORD dwSize); 00058 typedef bool(MACCEPTCALLBACK)(MSocketObj* pSocketObj); 00059 typedef bool(MDISCONNECTCLIENTCALLBACK)(MSocketObj* pSocketObj); 00060 00062 class MTCPSocketThread : public MThread 00063 { 00064 private: 00065 protected: 00066 MTCPSocket* m_pTCPSocket; 00067 MSignalEvent m_SendEvent; 00068 MSignalEvent m_KillEvent; 00069 CRITICAL_SECTION m_csSendLock; 00070 bool m_bActive; 00071 00072 DWORD m_nTotalSend; 00073 DWORD m_nTotalRecv; 00074 MTrafficLog m_SendTrafficLog; 00075 MTrafficLog m_RecvTrafficLog; 00076 00077 virtual void OnSocketError(SOCKET sock, SOCKET_ERROR_EVENT ErrorEvent, int &ErrorCode); 00078 public: 00079 MTCPSocketThread(MTCPSocket* pTCPSocket); 00080 ~MTCPSocketThread(); 00081 virtual void Run(); 00082 virtual void Create(); 00083 virtual void Destroy(); 00084 void LockSend() { EnterCriticalSection(&m_csSendLock); } 00085 void UnlockSend() { LeaveCriticalSection(&m_csSendLock); } 00086 bool IsActive() { return m_bActive; } 00087 00088 int GetSendTraffic() { return m_SendTrafficLog.GetTrafficSpeed(); } 00089 int GetRecvTraffic() { return m_RecvTrafficLog.GetTrafficSpeed(); } 00090 00091 void* m_pCallbackContext; 00092 MSOCKETERRORCALLBACK* m_fnSocketErrorCallback; 00093 }; 00094 00096 class MClientSocketThread : public MTCPSocketThread 00097 { 00098 private: 00099 protected: 00100 TCPSendList m_SendList; // Sending priority Low (Safe|Normal) Packet 00101 TCPSendList m_TempSendList; // Temporary Send List for Sync 00102 00103 size_t GetSendWaitQueueCount() { return m_TempSendList.size(); } 00104 00105 bool OnConnect(SOCKET sock); 00106 bool OnRecv(SOCKET socket, char* pPacket, DWORD dwSize); 00107 bool FlushSend(); 00108 bool Recv(); 00109 void ClearSendList(); 00110 public: 00111 MClientSocketThread(MTCPSocket* pTCPSocket); 00112 ~MClientSocketThread(); 00113 virtual void Run(); 00114 00115 bool PushSend(char* pPacket, DWORD dwPacketSize); 00116 00117 bool OnDisconnect(SOCKET sock); 00118 int GetSendItemCount() { return (int)m_SendList.size(); } 00119 00120 MCLIENTRECVCALLBACK* m_fnRecvCallback; 00121 MCONNECTCALLBACK* m_fnConnectCallback; 00122 MDISCONNECTCALLBACK* m_fnDisconnectCallback; 00123 }; 00124 00126 class MServerSocketThread : public MTCPSocketThread 00127 { 00128 private: 00129 WSAEVENT m_EventArray[WSA_MAXIMUM_WAIT_EVENTS]; 00130 protected: 00131 CRITICAL_SECTION m_csSocketLock; 00132 00133 bool OnRecv(MSocketObj* pSocketObj, char* pPacket, DWORD dwPacketSize); 00134 bool OnAccept(MSocketObj* pSocketObj); 00135 bool OnDisconnectClient(MSocketObj* pSocketObj); 00136 00137 bool FlushSend(); 00138 bool Recv(MSocketObj* pSocketObj); 00139 void FreeSocketObj(MSocketObj* pSocketObj); 00140 SocketListItor RemoveSocketObj(SocketListItor itor); 00141 void RenumberEventArray(); 00142 MSocketObj* InsertSocketObj(SOCKET sock, HANDLE event); 00143 public: 00144 MServerSocketThread(MTCPSocket* pTCPSocket); 00145 ~MServerSocketThread(); 00146 00147 void Disconnect(MSocketObj* pSocketObj); 00148 bool PushSend(MSocketObj* pSocketObj, char *pPacket, DWORD dwPacketSize); 00149 virtual void Run(); 00150 virtual void Destroy(); 00151 virtual void Create(); 00152 void LockSocket() { EnterCriticalSection(&m_csSocketLock); } 00153 void UnlockSocket() { LeaveCriticalSection(&m_csSocketLock); } 00154 00155 SocketList m_SocketList; 00156 00157 MSERVERRECVCALLBACK* m_fnRecvCallback; 00158 MACCEPTCALLBACK* m_fnAcceptCallback; 00159 MDISCONNECTCLIENTCALLBACK* m_fnDisconnectClientCallback; 00160 }; 00161 00163 class MTCPSocket 00164 { 00165 private: 00166 protected: 00167 bool m_bInitialized; 00168 int m_nPort; // 포트 00169 SOCKET m_Socket; // My Socket 00170 MTCPSocketThread* m_pSocketThread; 00171 00172 virtual bool Initialize(); 00173 virtual void Finalize(); 00174 virtual bool OpenSocket(); 00175 virtual void CloseSocket(); 00176 public: 00177 MTCPSocket(); 00178 virtual ~MTCPSocket(); 00179 SOCKET GetSocket() { return m_Socket; } 00180 int GetPort() { return m_nPort; } 00181 bool IsActive() { return m_pSocketThread->IsActive(); } 00182 void GetTraffic(int* nSendTraffic, int* nRecvTraffic) { 00183 *nSendTraffic = m_pSocketThread->GetSendTraffic(); 00184 *nRecvTraffic = m_pSocketThread->GetRecvTraffic(); 00185 } 00186 void SetSocketErrorCallback(MSOCKETERRORCALLBACK pCallback) 00187 { m_pSocketThread->m_fnSocketErrorCallback = pCallback; } 00188 void SetCallbackContext(void* pCallbackContext) 00189 { m_pSocketThread->m_pCallbackContext = pCallbackContext; } 00190 }; 00191 00193 class MServerSocket: public MTCPSocket 00194 { 00195 private: 00196 protected: 00197 sockaddr_in m_LocalAddress; // My IP and Port 00198 virtual void Finalize(); 00199 virtual bool Initialize(); 00200 virtual bool OpenSocket(int nPort); 00201 virtual void CloseSocket(); 00202 public: 00203 MServerSocket(); 00204 virtual ~MServerSocket(); 00205 00206 bool Listen(int nPort); 00207 bool Close(); 00208 bool Disconnect(MSocketObj* pSocketObj); // Server에서만 사용 00209 00210 bool Send(MSocketObj* pSocketObj, char* pPacket, DWORD dwPacketSize); 00211 00212 00213 void SetRecvCallback(MSERVERRECVCALLBACK pCallback) { ((MServerSocketThread*)(m_pSocketThread))->m_fnRecvCallback = pCallback; } 00214 void SetAcceptCallback(MACCEPTCALLBACK pCallback) { ((MServerSocketThread*)(m_pSocketThread))->m_fnAcceptCallback = pCallback; } 00215 void SetDisconnectClientCallback(MDISCONNECTCLIENTCALLBACK pCallback) { ((MServerSocketThread*)(m_pSocketThread))->m_fnDisconnectClientCallback = pCallback; } 00216 00217 SocketList* GetClientList() { return &((MServerSocketThread*)(m_pSocketThread))->m_SocketList; } 00218 00219 char* GetLocalIPString() { return inet_ntoa(m_LocalAddress.sin_addr); } 00220 DWORD GetLocalIP() { return m_LocalAddress.sin_addr.S_un.S_addr; } 00221 }; 00222 00224 class MClientSocket: public MTCPSocket 00225 { 00226 private: 00227 protected: 00228 char m_szHost[255]; // Hpst IP 00229 virtual void Finalize(); 00230 virtual bool Initialize(); 00231 virtual bool OpenSocket(); 00232 virtual void CloseSocket(); 00233 public: 00234 MClientSocket(); 00235 virtual ~MClientSocket(); 00236 00237 bool Connect(SOCKET* pSocket, char* szIP, int nPort); // Client에서만 사용 00238 bool Disconnect(); 00239 bool Send(char *pPacket, DWORD dwPacketSize); 00240 00241 void SetRecvCallback(MCLIENTRECVCALLBACK pCallback) { ((MClientSocketThread*)(m_pSocketThread))->m_fnRecvCallback = pCallback; } 00242 void SetConnectCallback(MCONNECTCALLBACK pCallback) { ((MClientSocketThread*)(m_pSocketThread))->m_fnConnectCallback = pCallback; } 00243 void SetDisconnectCallback(MDISCONNECTCALLBACK pCallback) { ((MClientSocketThread*)(m_pSocketThread))->m_fnDisconnectCallback = pCallback; } 00244 00245 const char* GetHost() { return m_szHost; } 00246 }; 00247 00248 00249 #pragma comment(lib, "ws2_32.lib") 00250 00251 #endif
MAIET entertainment