// // File : TSocketConnector.hh // // Purpose: Declaration of the class TSocketConnector // // $Id: TSocketConnector.hh 12063 2011-02-15 14:47:14Z mathes $ // /** @file TSocketConnector.hh * Declaration of the class TSocketConnector. * @author H.-J. Mathes, FzK */ #ifndef _FdRoot_TSocketConnector_hh_ #define _FdRoot_TSocketConnector_hh_ #include #include #include #include // ESockOptions // --- forward declaration(s) class TMonitor; class TObject; namespace FdRoot { /** This class implements a framework for a connection to a remote socket. */ class TSocketConnector { public: /** The name of the server host to which we connect by default. */ static const char kDefaultServerName[]; /** The default port at the server. */ static const unsigned short kDefaultServerPort = 4000; /** Constructor of the class TSocketConnector. */ TSocketConnector(); /** Virtual destructor of the class TSocketConnector. */ virtual ~TSocketConnector(); /** Close the existing socket to the server. */ virtual void Close(); /** Callback: called when a client has connected. */ virtual void Connect() {} /** Callback: called when a client has disconnected. */ virtual void Disconnect() {} /** Get the actual server name. */ std::string GetServerName() { return fServerName; } /** Get the actual server port. */ unsigned short GetServerPort() { return fServerPort; } /** Get the socket handle (TSocket) of the actual socket. * * The return value must be checked to be not NULL ! */ virtual TSocket* GetSocket() { return fSocket; } /** Get the status of the frameworks last operation. * * The error code from ROOT's TSocket (GetErrorCode()) is used. */ virtual int GetStatus() { return fStatus; } /** Called to handle all (user defined) messages types. * * @return true if message could be handled, false otherwise. */ virtual bool HandleMessage(TMessage*); /** @return true, if we currently have an active connection to the TCP * socket server, otherwise false. */ bool IsConnected() { return fIsConnected; } /** @return true if the socket is valid. */ bool IsValidSocket() { return (fSocket && (fSocket != (TSocket*)-1) && fSocket->IsValid()); } /** Create a socket to the server. * * The parameters (server and port) for that connection must be specified * before using the methods SetServerName() and SetServerPort(). * * @return true if operation was successful, false otherwise. */ virtual bool Open(unsigned int timeout=5); /** Create a socket to the server on the specified port. * * If the socket was already opened before, it will be closed. * * @param server name or IP-address of the server * @param port port number on the server * @param timeout timeout in seconds after which the connection request * is terminated with error * * @return true if operation was successful, false otherwise. */ virtual bool Open(const char *server, unsigned short port=kDefaultServerPort, unsigned int timeout=5); /** Create a socket to the server on the specified port. */ virtual bool Open(const std::string& server, unsigned short port=kDefaultServerPort, unsigned int timeout=5) { return Open(server.c_str(), port, timeout); } /** Run the server which might wait a specified time for a socket message. */ virtual void Run(Long_t millisec=20); /** Send an object (kMESS_OBJECT) via the socket. * * This method allows also to use other message types than the default. * * The return value of this method is the return value of * the underlying TSocket::Send*(), i.e.: * @li -1 in case of error. * @li -4 in case of kNoBlock and errno == EWOULDBLOCK * @li -5 (new) in case of invalid or non-existing socket */ virtual int Send(TObject*,int mtype=kMESS_OBJECT); /** Send an object already wrapped into a TMessage via the socket * (using kMESS_OBJECT). */ virtual int Send(TMessage*); /** Send a string like message (using kMESS_STRING) via the socket. */ virtual int Send(const char*); /** Send a string like message (using kMESS_STRING) via the socket. */ virtual int Send(const std::string& message) { return Send( message.c_str() ); } /** Set the timeout (in seconds) for the connect() to a remote socket. * * If the value is 0, connect() is done without timeout. */ void SetConnectTimeout(unsigned int timeout) { fConnectTimeout = timeout; } /** Set the timeout (in seconds) for the send() via socket. * * If the value is 0, send() is done without timeout. Not yet implemented! */ void SetSendTimeout(unsigned int timeout) { fSendTimeout = timeout; } /** If during a send operation the connection is broken, an attempt to * re-establish the connection is made, if this is desired. */ void SetReconnect(bool reconnect = true) { fDoReconnect = reconnect; } /** Set the name of the server host where the CDAS like TCP server resides. */ void SetServerName(const char *); void SetServerName(std::string name) { SetServerName( name.c_str() ); } /** Set the port of the CDAS like TCP socket server. */ void SetServerPort(unsigned short port) { fServerPort = port; } /** Set options for the TSocket. * * @see ROOT::TSocket.h for the possible ESockOptions. */ void SetSocketOption(ESockOptions opt,int val); /** Set the verbose print level of this class. */ static void SetPrintLevel(int level=1) { fgPrintLevel = level; } /** Check the validity of the socket to the remote end ... * * simply by trying to read from it. * * If we get a timeout, then it is still alive and 'true' is * returned. In the other case we close it, set all variables * accordingly and return 'false'. */ virtual bool TestConnection(); protected: /** Internal method of the TSocketConnector class. * * This method is called when the client is normally or abnormally * disconnected from the server. The socket is then removed * from the list of watched sockets of the TMonitor. Then the Disconnect() * method is called giving derived classes the possibility to add own * 'disconnect' specific actions. */ void CloseConnection(); /** Create the TSocket to the TCP socket server with a timeout. * * This method used the TSocket(int sock_fd) ctor call. If timeout * is 0, the standard TSocket(const char*, unsigned short) ctor is * used. */ TSocket * CreateSocketWithTimeout(const char *server,unsigned short port, unsigned int timeout=0); /** Default handler for string (kMESS_STRING) messages. */ bool HandleString(const char *); /** Default handler for object (kMESS_OBJECT) messages. */ bool HandleTObject(TObject*); /** Internal method of the TSocketConnector class. * * This method is called when the client has successfully connected to the * server. The client socket is then added to the TMonitor object for * further watching of its activities. * Then the Connect() method is called giving derived classes the * possibility to add own specific 'connect' specific actions. */ void OpenConnection(); void SetConnected(bool connected=true) { fIsConnected = connected; } /** Set the stored socket options for a newly created TSocket. */ void SetStoredSocketOptions(TSocket*); /** Try to open the connection again. * * @return true if reconnect was successful or connection still alive, * false otherwise. * * The method checks internally if the 'fDoReconnect' flag is set. */ bool TryReconnect(); private: // these ones are not implemented TSocketConnector(const TSocketConnector&); TSocketConnector& operator=(const TSocketConnector&); bool fDoReconnect; // if true, try automatic reconnect unsigned int fConnectTimeout; // timeout used for connect() unsigned int fSendTimeout; // timeout used for send() bool fIsConnected; // actual connection status TMonitor *fMonitor; // the socket monitor object std::string fServerName; // name of the server host unsigned short fServerPort; // port at the server host TSocket *fSocket; // the socket to the server int fStatus; // status of the last operation static int fgPrintLevel; std::map fOptionMap; }; } // namespace FdRoot #endif // _FdRoot_TSocketConnector_hh_