00001 #ifndef DV_SOCKET_H 00002 #define DV_SOCKET_H 00003 // $Id: socket.h,v 1.15 2003/03/04 18:03:02 dvermeir Exp $ 00004 00005 #include <iostream> 00006 #include <dvutil/ref.h> 00007 #include <dvutil/fdstreambuf.h> 00008 #include <dvnet/inetaddress.h> 00009 /** \file 00010 * The Dv::Net::Socket class provides a network connection as an iostream. 00011 */ 00012 namespace Dv { 00013 namespace Net { 00014 /** 00015 * Provide a network connection as an iostream. 00016 * 00017 * Example usage: 00018 * \code 00019 * Socket so("tinf2.vub.ac.be",8000) 00020 * if (so) { 00021 * so << "request" << endl; 00022 * string line; 00023 * while (getline(so,line)) 00024 * process_answer(line); 00025 * if (so.timedout()) 00026 * cerr << "Connection timed out"; 00027 * } 00028 * else { 00029 * cerr << so.strerror() << endl; 00030 * } 00031 * \endcode 00032 */ 00033 class Socket: public std::iostream { 00034 public: 00035 /** 00036 * Status codes, positive numbers are reserved for copies of the system errno. 00037 */ 00038 enum SOCKET_ERRORS { 00039 OK = 0, UNKNOWN_HOST = -1, CLOSED = -2, 00040 ACCEPT_ERROR = -3, WRONG_FAMILY = -4, 00041 EOFBIT = -5, BADBIT = -6, FAILBIT = -7, 00042 MAX_ERRNO = -7 }; 00043 /** 00044 * Set up a client connection to a host:port. 00045 * 00046 * \param host name of host to connect to. 00047 * \param port number of port to connect to. 00048 * \param bufsz size (in bytes) of input and output buffers. 00049 * \param delay (in milliseconds) time allowed for any I/O operation 00050 * to complete. A value of 0 means ``wait forever''. Note 00051 * that timedout() makes no sense if delay is 0. 00052 * \param non_blocking if true, the underlying fdstreambuf will be 00053 * non-blocking which prevents some cases of blocking I/O operations. 00054 * \param dbg pointer to stream to write debug to or 0 00055 * 00056 * \see timedout, connected, Dv::Util::fdstreambuf, debug 00057 */ 00058 Socket(const std::string& host, int port, size_t bufsz=1024, 00059 time_t delay=0, bool non_blocking=false, std::ostream* dbg=0); 00060 00061 /** Copy ctor. This function constructs a new Socket (iostream) and 00062 * associated fdstreambuf, based a new filedescriptor, obtained from 00063 * this Socket's file descriptor This function was introduced to 00064 * allow concurrent reading and writing to a connection (from 00065 * different threads). Experiments to do this failed when using the 00066 * same Socket object. If the writer uses a copy of the original 00067 * (which is used by the reader), the experiment works fine. 00068 * \param so socket whose file descriptor will be used to construct a 00069 * ``copy'' 00070 * \warning Closing a socket also shuts it down using shutdown(2) with 00071 * the SHUT_RDWR option, making all copies of this Socket unusable. However, 00072 * the underlying file descriptors of these copies are not closed. To 00073 * avoid a memory leak, they should be closed as well. 00074 */ 00075 00076 Socket(const Socket& so); 00077 /** 00078 * See the copy constructor. 00079 * \return reference to copy of this Socket 00080 * \see Socket::Socket(const Socket& so) 00081 */ 00082 Dv::Util::ref<Socket> dup(); 00083 00084 /** 00085 * Also closes socket using close(). 00086 * 00087 * \see close() 00088 */ 00089 ~Socket(); 00090 /** 00091 * Close underlying socket. This also does a \a shutdown(2) with the 00092 * \a SHUT_RDWR which prevents any transmissions and should 00093 * make all pending I/O calls return with an error. 00094 * 00095 * \see ~Socket 00096 */ 00097 void close(); 00098 /** 00099 * Try to (re)connect to the same host/port. 00100 * 00101 * \param delay (in milliseconds) time allowed for the connection to complete. 00102 * A value of 0 means ``wait forever''. 00103 * \return true iff the connect operation succeeded. 00104 * 00105 * If the constructor failed, it is possible to retry using connect(). 00106 * This may occur e.g. if the client is able to launch the server. 00107 * Note the delay parameter: when launching the server, at least 00108 * Solaris 7 needs a delay (e.g. 3 seems to work find). 00109 */ 00110 bool connect(unsigned int delay=0); 00111 /** 00112 * \return true iff last operation timed out 00113 * \see Socket::Socket() 00114 */ 00115 bool timedout() const; 00116 /** 00117 * Set timedout flag. Usually, the argument will be "false", such 00118 * that further I/O on the socket becomes possible. 00119 * @param new_timedout_status: true or (usually) false 00120 * @return true iff status change succeeded. It will fail e.g. if 00121 * the argument is "false" and the socket had not actually timed out, 00122 * or if the argument is "true" and socket status was not Socket::OK. 00123 * \code 00124 * ref<Socket> s; 00125 * size_t try(0); 00126 * 00127 * while ( (! getline(*s, line) ) && (++try <3) ) 00128 * if (s->timedout()) { 00129 * s->timedout(false); 00130 * else { 00131 * std::cerr << "I/O error: " << s->strerror() << std::endl; 00132 * break; 00133 * } 00134 * \endcode 00135 * \see Socket::Socket() Socket::timedout() 00136 */ 00137 bool timedout(bool new_timedout_status); 00138 /** 00139 * \return port number of Socket. 00140 */ 00141 int port() const { return port_; } 00142 /** 00143 * \return host name of Socket. 00144 */ 00145 const std::string& host() const { return host_; } 00146 /** 00147 * \return true iff last call to connect() was succesful. 00148 * \see connect, Socket::Socket 00149 */ 00150 bool connected() const { return connected_; } 00151 /** 00152 * \return status of Socket, only 0 is ok. 00153 * 00154 * A status of 0 means ok, positive integers correspond to system 00155 * errno values (man 2 errno). Negative numbers correspond to 00156 * ``specific'' errors for the Socket class (or its subclasses). 00157 * 00158 * The values EOFBIT, FAILBIT or BADBIT will be returned if the 00159 * corresponding bit in iostate is turned on and no other specific 00160 * error was detected. 00161 * 00162 * \see SOCKET_ERRORS 00163 */ 00164 int error() const; 00165 /** 00166 * Return string representation of error(). 00167 * This function is virtual because subclasses may want to add 00168 * their own error messages (but the convention of using negative 00169 * numbers for local error codes and positive ones for ::errno 00170 * values should be adhered to). 00171 */ 00172 virtual std::string strerror() const; 00173 /** 00174 * \return fdstreambuf associated with this socket or 0 if none. 00175 */ 00176 Dv::Util::fdstreambuf* rdbuf() const { 00177 return static_cast<Dv::Util::fdstreambuf*>(std::iostream::rdbuf()); } 00178 /** 00179 * \return underlying file descriptor (may be <0 if no connection). 00180 */ 00181 int sfd() const { return (rdbuf()->fd()); } 00182 /** 00183 * Create a new socket descriptor. 00184 * 00185 * \param syserr will contain system errorcode (::errno) if the 00186 * socket could not be created (and the return value is -1). 00187 * \return descriptor of a new socket or -1. 00188 * \see socket(2) 00189 */ 00190 static int mksocketfd(int& syserr); 00191 /** 00192 * Set a stream to write debug information to. A parameter 0 is 00193 * allowed and will turn off debugging. Note that this debug status 00194 * is independent of the Socket::rdbuf()->debug() facility which 00195 * can be used independently. 00196 * 00197 * \param dbg pointer to stream to write debug to or 0 00198 * \return previous value of debug() 00199 */ 00200 std::ostream* debug(std::ostream* dbg); 00201 /** 00202 * \return pointer to current debug stream or 0. 00203 */ 00204 std::ostream* debug(); 00205 protected: 00206 /** 00207 * Create a new socket and return associated fd, or -1 upon failure. 00208 * Upon failure, error will be set to the systems's errno. 00209 * 00210 * \return descriptor of a new socket or -1. 00211 * \see mksocketfd, error 00212 */ 00213 int mkfd(); 00214 /** 00215 * Set error status. 00216 * 00217 * \param e new error status. 00218 * \see error() 00219 */ 00220 void error(int e); 00221 00222 /** 00223 * Constructor for use by derived classes. 00224 * This constructor can e.g. be used by a Dv::Socket specialization 00225 * that encrypts the data traffic (by means of a class derived from 00226 * fdstreambuf). This function does not attempt to connect to 00227 * the given host/port. 00228 * 00229 * \param host name of host to connect to. 00230 * \param port number of port to connect to. 00231 * \param buffer fdstreambuf to use. This buffer must have been dynamically 00232 * allocated because Socket::~Socket() will delete it. 00233 * \param dbg pointer to stream to write debug to or 0 00234 * \see Socket::Socket, debug 00235 */ 00236 Socket(const std::string& host, int port, Dv::Util::fdstreambuf* buffer, std::ostream* dbg = 0); 00237 /** 00238 * Constructor for use by derived classes. 00239 * This constructor can e.g. be used by a Dv::Socket specialization 00240 * that encrypts the data traffic (by means of a class derived from 00241 * fdstreambuf). Socket::get_peer() will be used to fill in host and port. 00242 * 00243 * \param buffer fdstreambuf to use. This buffer must have been dynamically 00244 * allocated because Socket::~Socket() will delete it. 00245 * \param dbg pointer to stream to write debug to or 0 00246 * \see get_peer, debug 00247 */ 00248 Socket(Dv::Util::fdstreambuf* buffer, std::ostream* dbg = 0); 00249 private: 00250 /** 00251 * Host this socket refers to. 00252 */ 00253 std::string host_; 00254 /** 00255 * Port number this socket refers to. 00256 */ 00257 int port_; 00258 /** 00259 * Error status of socket. 00260 * \see error() 00261 */ 00262 mutable int errno_; 00263 /** 00264 * Whether socket is connected. 00265 * \see connected() 00266 */ 00267 bool connected_; 00268 /** 00269 * Pointer to debug output stream. 00270 * \see debug() 00271 */ 00272 std::ostream* debug_; 00273 00274 /** 00275 * No copy ctor. 00276 Socket(const Socket&); // forbidden 00277 */ 00278 /** 00279 * No assignment. 00280 */ 00281 Socket& operator=(const Socket&); // forbidden 00282 00283 /** 00284 * Set host_ and port_. 00285 * \see getpeername(2). 00286 */ 00287 bool get_peer(); 00288 00289 /** 00290 * Friend class that can use buf2socket() 00291 */ 00292 friend class ServerSocket; 00293 /** 00294 * Used by ServerSocket. 00295 */ 00296 static Dv::Util::ref<Socket> buf2socket(Dv::Util::fdstreambuf*); 00297 }; 00298 00299 }} 00300 00301 #endif 00302
dvnet-0.9.11 | [27 December, 2004] |