// ThreadedSocket.h: interface for the CThreadedSocket class. // ////////////////////////////////////////////////////////////////////// #pragma once class CThreadedSocketException { public: // Constructor CThreadedSocketException(char* pchMessage); public: ~CThreadedSocketException() {} virtual bool GetErrorMessage(string& lpstrError, unsigned int nMaxError, unsigned int * pnHelpContext = 0); int GetError() { return m_nError; }; private: int m_nError; char * m_strMessage; }; class CThreadedSocket { public: CThreadedSocket(); virtual ~CThreadedSocket(); // Construction public: void Create(unsigned int nSocketPort = 0, int nSocketType=SOCK_STREAM, long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE, const char * lpszSocketAddress = 0); // Attributes public: SOCKET m_hSocket; operator SOCKET() const; void GetPeerName(string & rPeerAddress, unsigned int& rPeerPort); void GetSockName(string & rSocketAddress, unsigned int& rSocketPort); // Operations public: void Socket(int nSocketType=SOCK_STREAM, long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE, int nProtocolType = 0, int nAddressFormat = PF_INET); void AddMember( const char * lpszHostAddress ); virtual void Accept(CThreadedSocket& rConnectedSocket, SOCKADDR* lpSockAddr = NULL, int* lpSockAddrLen = NULL); void Bind(unsigned int nSocketPort, const char * lpszSocketAddress = 0); virtual void Close(); bool Connect(const char * lpszHostAddress, unsigned int nHostPort); bool Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen); virtual int Receive(void* lpBuf, int nBufLen, int nFlags = 0); int ReceiveFrom(void* lpBuf, int nBufLen, string & rSocketAddress, unsigned int & rSocketPort, int nFlags = 0); enum { receives = 0, sends = 1, both = 2 }; virtual void Send(const void* lpBuf, int nBufLen, int nFlags = 0); void SendTo(const void* lpBuf, int nBufLen, unsigned int nHostPort, const char * lpszHostAddress = 0, int nFlags = 0); void AsyncSelect(long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE); inline CThreadedSocket::operator SOCKET() const { return m_hSocket; } inline void GetPeerName(SOCKADDR* lpSockAddr, int* lpSockAddrLen) { if ( getpeername(m_hSocket, lpSockAddr, lpSockAddrLen) == SOCKET_ERROR) throw ( new CThreadedSocketException( "getpeername" ) ); } inline void GetSockName(SOCKADDR* lpSockAddr, int* lpSockAddrLen) { if ( getsockname(m_hSocket, lpSockAddr, lpSockAddrLen)== SOCKET_ERROR) throw( new CThreadedSocketException( "getsockname" ) ); } inline void SetSockOpt(int nOptionName, const void* lpOptionValue, int nOptionLen, int nLevel = SOL_SOCKET) { if ( setsockopt(m_hSocket, nLevel, nOptionName, (LPCSTR)lpOptionValue, nOptionLen)== SOCKET_ERROR) throw( new CThreadedSocketException( "setsockopt" ) ); } inline void GetSockOpt(int nOptionName, void* lpOptionValue, int* lpOptionLen, int nLevel = SOL_SOCKET) { if ( getsockopt(m_hSocket, nLevel, nOptionName, (LPSTR)lpOptionValue, lpOptionLen)== SOCKET_ERROR) throw( new CThreadedSocketException( "getsockopt" ) ); } static inline int CThreadedSocket::GetLastError() { return WSAGetLastError(); } inline void Bind(const SOCKADDR* lpSockAddr, int nSockAddrLen) { if ( bind(m_hSocket, lpSockAddr, nSockAddrLen)== SOCKET_ERROR ) throw( new CThreadedSocketException( "bind" )); } inline void IOCtl(long lCommand, unsigned long* lpArgument) { if ( ioctlsocket(m_hSocket, lCommand, lpArgument)== SOCKET_ERROR) throw( new CThreadedSocketException( "bind" ) ); } inline void Listen(int nConnectionBacklog=5) { if ( listen(m_hSocket, nConnectionBacklog)== SOCKET_ERROR) throw( new CThreadedSocketException( "listen" ) ); } inline int ReceiveFrom(void* lpBuf, int nBufLen, SOCKADDR* lpSockAddr, int* lpSockAddrLen, int nFlags = 0) { int lg = recvfrom(m_hSocket, (LPSTR)lpBuf, nBufLen, nFlags, lpSockAddr, lpSockAddrLen); if ( lg == SOCKET_ERROR ) throw( new CThreadedSocketException( "recvfrom" ) ); return lg; } inline bool ShutDown(int nHow = sends) { if ( shutdown(m_hSocket,nHow) == SOCKET_ERROR ) throw( new CThreadedSocketException( "shutdown" ) ); } inline void SendTo(const void* lpBuf, int nBufLen, const SOCKADDR* lpSockAddr, int nSockAddrLen, int nFlags = 0) { if ( sendto(m_hSocket, (LPSTR)lpBuf, nBufLen, nFlags, lpSockAddr, nSockAddrLen)== SOCKET_ERROR ) throw( new CThreadedSocketException( "sendto" ) ); } // Overridable callbacks protected: virtual void OnWakeup(); virtual void OnReceive(int nErrorCode); virtual void OnSend(int nErrorCode); virtual void OnOutOfBandData(int nErrorCode); virtual void OnAccept(int nErrorCode); virtual void OnConnect(int nErrorCode); virtual void OnClose(int nErrorCode); // Implementation void StartListener(long lEvent); long m_EventMask; unsigned long thread_id; HANDLE h_thread; WSAEVENT m_hEvent[2]; // socket event for receive and send actions unsigned int SocketThread(); //Client Thread // wrapper for thread routine static DWORD WINAPI SocketThreadProc( void * pParam ); };