// ThreadedSocket.h: interface for the CThreadedSocket class. // ////////////////////////////////////////////////////////////////////// #pragma once class CThreadedSocket { public: CThreadedSocket(); virtual ~CThreadedSocket(); // Construction public: int Create(unsigned int nSocketPort = 0, int nSocketType=SOCK_STREAM, const char * lpszSocketAddress = 0); // Attributes public: SOCKET m_hSocket; inline operator SOCKET() const { return m_hSocket; }; void GetPeerName(ivy::string & rPeerAddress, unsigned int& rPeerPort); void GetSockName(ivy::string & rSocketAddress, unsigned int& rSocketPort); // Operations public: SOCKET Socket(int nSocketType=SOCK_STREAM, int nProtocolType = 0, int nAddressFormat = PF_INET); int AddMember( const char * lpszHostAddress ); virtual SOCKET Accept(CThreadedSocket& rConnectedSocket, SOCKADDR* lpSockAddr = NULL, int* lpSockAddrLen = NULL); int Bind(unsigned int nSocketPort, const char * lpszSocketAddress = 0); virtual void Close(); int Connect(const char * lpszHostAddress, unsigned int nHostPort); int Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen); int Listen(int nConnectionBacklog=5); virtual size_t Receive(void* lpBuf, size_t nBufLen, int nFlags = 0); size_t ReceiveFrom(void* lpBuf, size_t nBufLen, ivy::string & rSocketAddress, unsigned int & rSocketPort, int nFlags = 0); enum { receives = 0, sends = 1, both = 2 }; virtual size_t Send(const void* lpBuf, size_t nBufLen, int nFlags = 0); size_t SendTo(const void* lpBuf, size_t nBufLen, unsigned int nHostPort, const char * lpszHostAddress = 0, int nFlags = 0); inline int GetPeerName(SOCKADDR* lpSockAddr, int* lpSockAddrLen) { return getpeername(m_hSocket, lpSockAddr, lpSockAddrLen); } inline int GetSockName(SOCKADDR* lpSockAddr, int* lpSockAddrLen) { return getsockname(m_hSocket, lpSockAddr, lpSockAddrLen); } inline int SetSockOpt(int nOptionName, const void* lpOptionValue, int nOptionLen, int nLevel = SOL_SOCKET) { return setsockopt(m_hSocket, nLevel, nOptionName, (LPCSTR)lpOptionValue, nOptionLen); } inline int GetSockOpt(int nOptionName, void* lpOptionValue, int* lpOptionLen, int nLevel = SOL_SOCKET) { return getsockopt(m_hSocket, nLevel, nOptionName, (LPSTR)lpOptionValue, lpOptionLen); } static inline int CThreadedSocket::GetLastError() { return ::WSAGetLastError(); } inline int Bind(const SOCKADDR* lpSockAddr, int nSockAddrLen) { return bind(m_hSocket, lpSockAddr, nSockAddrLen); } inline int IOCtl(long lCommand, unsigned long* lpArgument) { return ioctlsocket(m_hSocket, lCommand, lpArgument); } inline size_t ReceiveFrom(void* lpBuf, size_t nBufLen, SOCKADDR* lpSockAddr, size_t* lpSockAddrLen, int nFlags = 0) { int len = (int)*lpSockAddrLen; // Non conforme a Unix size_t lg = recvfrom(m_hSocket, (LPSTR)lpBuf, (int)nBufLen, nFlags, lpSockAddr, &len); *lpSockAddrLen = len; return lg; } inline int ShutDown(int nHow = sends) { return shutdown(m_hSocket,nHow); } inline size_t SendTo(const void* lpBuf, size_t nBufLen, const SOCKADDR* lpSockAddr, size_t nSockAddrLen, int nFlags = 0) { return sendto(m_hSocket, (LPSTR)lpBuf, (int)nBufLen, nFlags, lpSockAddr, (int)nSockAddrLen); } // Overridable callbacks protected: 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 int StartListener(); int StartWriter(); bool SignalWriter(); HANDLE h_reader; HANDLE h_writer; unsigned long reader_id; unsigned long writer_id; unsigned int SocketReader(); //Receiver Thread unsigned int SocketWriter(); //Sender Thread bool listen_mode; bool connect_pending; bool send_pending; HANDLE send_count; // wrapper for thread routine static DWORD WINAPI SocketReaderProc( void * pParam ); static DWORD WINAPI SocketWriterProc( void * pParam ); };