![]() |
Main Page
Class Hierarchy
Alphabetical List
Compound List
File List
Compound Members
![]() |
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