#ifndef _CSESSION_H_ #define _CSESSION_H_ #include #include #include #include #include "SessionPolicy.h" #include "../Address/INET_Addr.h" #include "../IOCP/Overlapped.h" #include "../../Thread/Lock.h" #include "../../Stream/Buffer/BufferQueue.h" #pragma comment(lib, "ws2_32") // Àü¹æ ÂüÁ¶ class CBuffer; class CBufferFactory; class CPacketDispatch; class CDispatchFactory; class CCompletionHandler; class CSocketBaseFactory; struct SessionStatistics { unsigned long m_dwTotalReceived; // ¼¼¼ÇÀÌ ¹ÞÀº ¾ç. unsigned long m_dwTotalSendPending; // ¼¼¼Ç¿¡¼­ pendingÇÑ ¾ç. unsigned long m_dwTotalSendCompleted; // Send¿Ï·áµÈ ¾ç. time_t m_ConnectedTime; // ConnectµÈ ½Ã°£. time_t m_DisconnectedTime; // DisconnectedµÈ ½Ã°£. SessionStatistics::SessionStatistics() : m_dwTotalReceived(0), m_dwTotalSendPending(0), m_dwTotalSendCompleted(0), m_ConnectedTime(0), m_DisconnectedTime(0) { } void Initialize() { m_dwTotalReceived = m_dwTotalSendPending = m_dwTotalSendCompleted = 0; m_ConnectedTime = m_DisconnectedTime = 0; } }; class CSession { public: CSession(CSessionPolicy& SessionPolicy); ~CSession(); enum SendResult { SEND_SUCCEEDED, SEND_FAILED, SEND_NEXT_TURN, }; LONG AddRef(); LONG Release(); bool IsConnected(); void CloseSession(); bool CalledConnected(); bool CalledDisconnected(); void SetAddress(INET_Addr& remoteAddr, INET_Addr& localAddr); INET_Addr& GetRemoteAddr() { return m_RemoteAddr; } INET_Addr& GetLocalAddr() { return m_LocalAddr; } CPacketDispatch* GetDispatch() { return m_lpDispatch; } CSessionPolicy& GetPolicy() { return m_SessionPolicy; } const SessionStatistics& GetStatistics() { return m_Statistics; } bool SendPending(CBuffer* lpBuffer); void SendCompleted(BOOL bResult, unsigned long dwSendedBytes); bool Process(); bool Dispatch(unsigned long dwReceivedBytes); bool Recv() { SessionLock::Syncronize sync(m_SessionLock); return InternalRecv(); } bool RecvFrom() { SessionLock::Syncronize sync(m_SessionLock); return InternalRecvFrom(); } bool Send() { SessionLock::Syncronize sync(m_SessionLock); return InternalSend(); } bool Connect(CCompletionHandler& Handler, LPSTR lpConnectAddress, unsigned short usPort); bool Shutdown(); void SuspendRecv(); void ResumeRecv(); friend std::ostream& Log(std::ostream& strm, CSession* lpSession) { return (0 != lpSession) ? lpSession->PrintStatistics(strm) : strm; } friend std::ostream& Log(std::ostream& strm, CSession& Session) { return Session.PrintStatistics(strm); } private: bool isValid() const { return (0 != m_lpRecvBuffer && 0 != m_lpDispatch); } void Socket(SOCKET hSocket) { m_hSocket = hSocket; } SOCKET Socket() { return m_hSocket; } bool InternalRecv(); bool InternalRecvFrom(); bool InternalSend(); SendResult InternalSend(CBuffer* lpBuffer); SendResult InternalSendTo(CBuffer* lpBuffer); void InternalCloseSocket(); // Desc : ·Î±× Ãâ·Â std::ostream& PrintStatistics(std::ostream& strm); int InternalPrintStatistics(char* szBuffer, int nBufferLen); // ------------------------------------------------------------------------- // ¸â¹ö º¯¼ö ¼±¾ð typedef CCSLock SessionLock; // Critical Section Lock (24byte) SessionLock m_SessionLock; // Multithreadȯ°æÀ» À§ÇÑ Lock CACHE_PAD(LockPadding, sizeof(SessionLock));// Cache-alignÀ» À§ÇÑ Padding // Shared class CSessionPolicy& m_SessionPolicy; // Session Policy // Per-session data CPacketDispatch* m_lpDispatch; // ¼¼¼ÇÀÇ PacketDispatchŬ·¡½º SOCKET m_hSocket; // Socket Descriptor INET_Addr m_RemoteAddr; // »ó´ë¹æÀÇ ÁÖ¼Ò INET_Addr m_LocalAddr; // ³ªÀÇ ÁÖ¼Ò CBuffer* m_lpRecvBuffer; // Recv Buffer CBufferQueue m_SendQueue; // SendQueue unsigned long m_dwRecvPending; // Recv PendingCount unsigned long m_dwSendPending; // Send PendingCount LONG m_nRefCount; // ¼¼¼Ç ¸®ÆÛ·±½º Ä«¿îÆ® SessionStatistics m_Statistics; // ¼¼¼Ç Åë°è unsigned char m_cCurrentStatus; // ¼¼¼Ç »óÅ unsigned char m_cFlags; // ¼¼¼Ç flag unsigned short m_usPadding; // ÆÐµù°ª friend class CListener; friend class CIOCPNet; }; #endif