//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // //===========================================================================// #ifndef SOCKET_CREATOR_H #define SOCKET_CREATOR_H #ifdef _WIN32 #pragma once #endif #include "tier1/utlvector.h" #include "tier1/utlbuffer.h" #include "tier1/utllinkedlist.h" #include "tier1/netadr.h" #include "igameserverdata.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" typedef int SocketHandle_t; struct ISocketCreatorListener { public: // Methods to allow other classes to allocate data associated w/ sockets // Return false to disallow socket acceptance virtual bool ShouldAcceptSocket( SocketHandle_t hSocket, const netadr_t &netAdr ) = 0; virtual void OnSocketAccepted( SocketHandle_t hSocket, const netadr_t &netAdr, void** ppData ) = 0; virtual void OnSocketClosed( SocketHandle_t hSocket, const netadr_t &netAdr, void* pData ) = 0; }; //----------------------------------------------------------------------------- // container class to handle network streams //----------------------------------------------------------------------------- class CSocketCreator { public: CSocketCreator( ISocketCreatorListener *pListener = NULL ); ~CSocketCreator(); // Call this once per frame void RunFrame(); // This method is used to put the socket in a mode where it's listening // for connections and a connection is made once the request is received bool CreateListenSocket( const netadr_t &netAdr ); void CloseListenSocket(); bool IsListening() const; // This method is used to connect to/disconnect from an external listening socket creator // Returns accepted socket index, or -1 if it failed. // Use GetAcceptedSocket* methods to access this socket's data // if bSingleSocket == true, all accepted sockets are closed before the new one is opened // NOTE: Closing an accepted socket will re-index all the sockets with higher indices int ConnectSocket( const netadr_t &netAdr, bool bSingleSocket ); void CloseAcceptedSocket( int nIndex ); void CloseAllAcceptedSockets(); int GetAcceptedSocketCount() const; SocketHandle_t GetAcceptedSocketHandle( int nIndex ) const; const netadr_t& GetAcceptedSocketAddress( int nIndex ) const; void* GetAcceptedSocketData( int nIndex ); // Closes all open sockets (listen + accepted) void Disconnect(); private: enum { SOCKET_TCP_MAX_ACCEPTS = 2 }; void ProcessAccept(); bool ConfigureSocket( int sock ); public: struct AcceptedSocket_t { SocketHandle_t m_hSocket; netadr_t m_Address; void *m_pData; bool operator==( const AcceptedSocket_t &rhs ) const { return ( m_Address.CompareAdr( rhs.m_Address ) == 0 ); } }; ISocketCreatorListener *m_pListener; CUtlVector< AcceptedSocket_t > m_hAcceptedSockets; SocketHandle_t m_hListenSocket; // Used to accept connections netadr_t m_ListenAddress; // Address used to listen on }; //----------------------------------------------------------------------------- // Returns true if the socket would block because of the last socket command //----------------------------------------------------------------------------- bool SocketWouldBlock(); #endif // SOCKET_CREATOR_H