Main Page Class Hierarchy Alphabetical List Compound List File List Compound Members

FXSocket.h

Go to the documentation of this file.
00001 /********************************************************************************
00002 *                                                                               *
00003 *                  Generic socket I/O handling                                  *
00004 *                                                                               *
00005 *********************************************************************************
00006 * Copyright (C) 2003 by Mathew Robertson.   All Rights Reserved.                *
00007 *********************************************************************************
00008 * This library is free software; you can redistribute it and/or                 *
00009 * modify it under the terms of the GNU Lesser General Public                    *
00010 * License as published by the Free Software Foundation; either                  *
00011 * version 2.1 of the License, or (at your option) any later version.            *
00012 *                                                                               *
00013 * This library is distributed in the hope that it will be useful,               *
00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of                *
00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU             *
00016 * Lesser General Public License for more details.                               *
00017 *                                                                               *
00018 * You should have received a copy of the GNU Lesser General Public              *
00019 * License along with this library; if not, write to the Free Software           *
00020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.    *
00021 *********************************************************************************/
00022 #ifndef FXSOCKET_H
00023 #define FXSOCKET_H
00024 
00025 #ifndef FXIOHANDLE_H
00026 #include "FXIOHandle.h"
00027 #endif
00028 namespace FXEX {
00029 class FXResolver;
00030 
00031 /**
00032  * This is the base class of the socket server and socket client classes.
00033  * It can be instantiated on its own if the user wants to have more control over
00034  * the connection process.
00035  * 
00036  * It is intend to be used in these scenarios:
00037  * a) Application creates an FXSocket object and calls connect(...) to connect to the remote host.
00038  *    All socket reads are forwarded to the application using a SEL_COMMAND with data of
00039  *    FXSocketData*
00040  * b) Applicaiton creates an FXSocket object and calls listen(...) to listen for any
00041  *    incoming connections.   The application must handle the SEL_OPENED message, with
00042  *    data FXSocket*, and manage a list of incoming connections.
00043  * c) App creats an FXSocketClient which connect to a socket server.
00044  *
00045  * Important: if you are using this class on Win32, then the FXInputHandle is in reality
00046  *            a struct win32socket_t* - this is the only way I could think of to implement
00047  *            it reasonably cleanly...  As such you shouldn't directly manipulate the
00048  *            FXInputHandle...  In most cases, you wont need to care about this...
00049  *
00050  * For an example, see the socketserver/socketclient demos in the tests directory
00051  */
00052 class FXAPI FXSocket : public FXIOHandle {
00053   FXDECLARE (FXSocket)
00054 
00055   protected:
00056     FXString         hostname;          // hostname of remote connection or "localhost" for listener
00057     FXint            port;              // socket port
00058     FXSocketFamily   family;            // socket family (internet/unix)
00059     FXSocketType     type;              // socket type (stream/datagram/raw)
00060     FXResolver      *resolver;          // asynchronous hostname resolver
00061 
00062   private:
00063   
00064     /// helper used to send data
00065     FXbool writeAgain();
00066 
00067     /// helper to add this socket to the FXApp watch list
00068     virtual FXbool addSocketInput();
00069 
00070     /// setup various socket options
00071     FXbool setSocketOptions();
00072 
00073   public:
00074     enum {
00075       ID_SOCKET=FXIOHandle::ID_LAST,
00076       ID_CONNECT,
00077       ID_RESOLVE,
00078       ID_LAST
00079       };
00080 
00081   public:
00082     long onRead(FXObject*,FXSelector,void*);
00083     long onExcept(FXObject*,FXSelector,void*);
00084     long onConnect(FXObject*,FXSelector,void*);
00085     long onOpened(FXObject*,FXSelector,void*);
00086     long onClose(FXObject*,FXSelector,void*);
00087     long onConnectResolved(FXObject*,FXSelector,void*);
00088 
00089   protected:
00090 
00091     /// for serialisation
00092     FXSocket();
00093 
00094     /// helper routine - returns the filesystem path of the local domain socket
00095     FXString getLocalDomainPath();
00096 
00097     /// close the underlying operating system handle
00098     virtual void closehandle();
00099 
00100     /// instantiates this class
00101     virtual FXSocket* newInstance(FXInputHandle h);
00102 
00103     /// Create a socket using a specific port
00104     FXSocket(FXApp *a,FXint port,FXObject *tgt=NULL,FXSelector sel=0,
00105              FXSocketFamily family=FXSocketFamilyInet, FXSocketType type=FXSocketTypeStream);
00106 
00107     /// Create a socket using a specific service
00108     FXSocket(FXApp *a,const FXString& service,FXObject *tgt=NULL,FXSelector sel=0,
00109              FXSocketFamily family=FXSocketFamilyInet, FXSocketType type=FXSocketTypeStream);
00110 
00111   public:
00112 
00113     /// Use an existing socket, adding it to the FXApp event loop
00114     FXSocket(FXInputHandle s,FXApp *a,FXObject *tgt=NULL,FXSelector sel=0);
00115 
00116     /// create resource
00117     virtual void create();
00118 
00119     /// return the file descriptor / event handle
00120     virtual FXInputHandle getHandle();
00121 
00122     /**
00123      * Set the hostname to a different one; you cannot change this once the connection is
00124      * open - doing so just silently fails ;-)
00125      */
00126     void setHostname(const FXString& host);
00127 
00128     /**
00129      * Gets the hostname, either the name you specified (for an outbound connection),
00130      * or the hostname of the remote end _if it can be determined_ for inbound connection.
00131      */
00132     FXString getHostname() { return hostname; }
00133 
00134     /**
00135      * Set the port to a different one; you cannot change this once the connection is
00136      * open - doing so just silently fails ;-)
00137      */
00138     void setPort(FXint port);
00139 
00140     /// gets the port
00141     FXint getPort() { return port; }
00142 
00143     /// set the socket family
00144     void setSocketFamily(FXSocketFamily family);
00145 
00146     /// return the family used in this socket
00147     FXSocketFamily getSocketFamily() { return family; }
00148 
00149     /// set the socket type
00150     void setSocketType(FXSocketType type);
00151 
00152     /// return the scoket type for this socket
00153     FXSocketType getSocketType() { return type; }
00154 
00155     /// Open-up/create a socket
00156     virtual FXbool open();
00157 
00158     /// Close down the socket
00159     virtual void close();
00160 
00161     /**
00162      * Send a file down the socket.
00163      * Since most operating systems provide some form of native implementation for doing
00164      * this in an efficient manner, we provide an interface here.  This call could
00165      * be implemented better, by sending the file in another thread; avoids the need
00166      * for the GUI to block.
00167      */
00168     FXbool sendfile(const FXString& file);
00169 
00170     /**
00171      * Get some data from the socket
00172      * - a wrapper for the recv() syscall
00173      */
00174     FXint read(FXuchar *data,FXint len,FXbool outOfBand=FALSE);
00175 
00176     /**
00177      * Send some data over the socket - can send out of band data if required
00178      * - a wrapper for the send() syscall
00179      */
00180     FXint write(FXuchar *data,FXint n,FXbool outOfBand=FALSE);
00181 
00182     /// read the socket and generate FOX events
00183     FXbool readData(FXbool outOfBand=FALSE);
00184 
00185     /**
00186      * Connect socket to this host
00187      * Note: This can return FALSE for a 'not-yet-connected' socket
00188      *       ie the app should handle the SEL_OPENED event
00189      */
00190     FXbool connect(const FXString& host);
00191 
00192     /// setup socket to listen for incoming connections
00193     FXbool listen(FXint concurrent);
00194 
00195     /// accept an incoming socket connection
00196     FXSocket* accept();
00197 
00198     /// get the hostname of the remote machine
00199     static FXString getRemoteHostname(FXInputHandle s);
00200 
00201     /// get the port number of the remote port
00202     static FXint getRemotePort(FXInputHandle s);
00203 
00204     /// get socket family for a socket
00205     static FXSocketFamily getSocketFamily(FXInputHandle s);
00206 
00207     /// get the socket type (stream, datagram, raw...)
00208     static FXSocketType getSocketType(FXInputHandle s);
00209     
00210     /// duplicate this socket onto another socket - defaults to OS assigned descriptor
00211     FXSocket* duplicate(FXInputHandle newHandle=INVALID_HANDLE);
00212 
00213     /// save object to stream
00214     virtual void save(FXStream& store) const;
00215 
00216     /// load object from stream
00217     virtual void load(FXStream& store);
00218 
00219     /// dtor
00220     virtual ~FXSocket();
00221   };
00222 
00223 } // namespace FXEX
00224 #endif // FXSOCKET_H