CSCommon: MTCPSocket.h 소스 파일

MAIET

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