skstream
|
00001 /************************************************************************** 00002 FreeSockets - Portable C++ classes for IP(sockets) applications. (v0.3) 00003 Copyright (C) 2000-2001 Rafael Guterres Jeffman 00004 (C) 2002-2006 Alistair Riddoch 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 00020 **************************************************************************/ 00021 00029 #ifndef RGJ_FREE_STREAM_H_ 00030 #define RGJ_FREE_STREAM_H_ 00031 00032 #include <iostream> 00033 00034 #include <skstream/sksocket.h> 00035 00036 // To not include full <cstdio>, we define only EOF 00037 #ifndef EOF 00038 #define EOF (-1) 00039 #endif 00040 00042 // class socketbuf 00044 00046 class socketbuf : public std::streambuf { 00047 private: 00048 std::streambuf::char_type *_buffer; 00049 00050 protected: 00051 SOCKET_TYPE _socket; 00052 00053 timeval _underflow_timeout; 00054 timeval _overflow_timeout; 00055 00056 private: 00058 socketbuf(const socketbuf&); 00060 socketbuf& operator=(const socketbuf&); 00061 00062 protected: 00063 bool Timeout; 00064 00065 public: 00069 explicit socketbuf(SOCKET_TYPE sock, std::streamsize insize = 0x8000, 00070 std::streamsize outsize = 0x8000); 00074 socketbuf(SOCKET_TYPE sock, std::streambuf::char_type * buf, 00075 std::streamsize length); 00076 00078 virtual ~socketbuf(); 00079 00081 void setSocket(SOCKET_TYPE sock); 00082 00084 SOCKET_TYPE getSocket() const { 00085 return _socket; 00086 } 00087 00091 void setReadTimeout(unsigned sec, unsigned usec=0) { 00092 _underflow_timeout.tv_sec = sec; 00093 _underflow_timeout.tv_usec = usec; 00094 } 00095 00099 void setWriteTimeout(unsigned sec, unsigned usec=0) { 00100 _overflow_timeout.tv_sec = sec; 00101 _overflow_timeout.tv_usec = usec; 00102 } 00103 00104 void setTimeout(unsigned sec, unsigned usec=0) { 00105 setWriteTimeout(sec, usec); 00106 } 00107 00109 bool timeout() const { 00110 return Timeout; 00111 } 00112 00113 protected: 00115 virtual int_type overflow(int_type nCh = traits_type::eof()) = 0; 00117 virtual int_type underflow() = 0; 00118 00120 virtual int sync(); 00121 00125 std::streambuf * setbuf(std::streambuf::char_type * buf, std::streamsize len); 00126 }; 00127 00129 class stream_socketbuf : public socketbuf { 00130 public: 00134 explicit stream_socketbuf(SOCKET_TYPE sock, 00135 std::streamsize insize = 0x8000, 00136 std::streamsize outsize = 0x8000); 00140 stream_socketbuf(SOCKET_TYPE sock, std::streambuf::char_type * buf, 00141 std::streamsize length); 00142 00144 virtual ~stream_socketbuf(); 00145 00146 protected: 00148 virtual int_type overflow(int_type nCh = traits_type::eof()); 00150 virtual int_type underflow(); 00151 00152 }; 00153 00155 class dgram_socketbuf : public socketbuf { 00156 public: 00160 explicit dgram_socketbuf(SOCKET_TYPE sock, std::streamsize insize = 0x8000, 00161 std::streamsize outsize = 0x8000); 00165 dgram_socketbuf(SOCKET_TYPE sock, 00166 std::streambuf::char_type * buf, 00167 std::streamsize length); 00168 00170 virtual ~dgram_socketbuf(); 00171 00172 bool setTarget(const std::string& address, unsigned port, int proto); 00173 00174 void setOutpeer(const sockaddr_storage & peer) { 00175 out_peer = peer; 00176 } 00177 00178 const sockaddr_storage & getOutpeer() const { 00179 return out_peer; 00180 } 00181 00182 const sockaddr_storage & getInpeer() const { 00183 return in_peer; 00184 } 00185 00186 SOCKLEN getOutpeerSize() const { 00187 return out_p_size; 00188 } 00189 00190 SOCKLEN getInpeerSize() const { 00191 return in_p_size; 00192 } 00193 00194 protected: 00196 sockaddr_storage out_peer; 00198 sockaddr_storage in_peer; 00200 SOCKLEN out_p_size; 00202 SOCKLEN in_p_size; 00203 00205 virtual int_type overflow(int_type nCh = traits_type::eof()); 00207 virtual int_type underflow(); 00208 00209 }; 00210 00212 // class socket_stream 00214 00216 class basic_socket_stream : public basic_socket, public std::iostream { 00217 protected: 00218 socketbuf & _sockbuf; 00219 int m_protocol; 00220 00221 public: 00223 basic_socket_stream(socketbuf & buffer, int proto = FreeSockets::proto_IP); 00224 00225 // Destructor 00226 virtual ~basic_socket_stream(); 00227 00228 bool fail(); 00229 00230 bool operator!() { 00231 return fail(); 00232 } 00233 00234 bool timeout() const { 00235 return _sockbuf.timeout(); 00236 } 00237 00238 virtual SOCKET_TYPE getSocket() const; 00239 00240 // Needs to be virtual to handle in-progress connect()'s for 00241 // tcp sockets 00242 virtual void close(); 00243 00244 void shutdown(bool wr_only = false); 00245 00246 void setSocket(SOCKET_TYPE sock) { 00247 _sockbuf.setSocket(sock); 00248 } 00249 00250 void setTimeout(unsigned sec, unsigned usec=0) { 00251 _sockbuf.setTimeout(sec,usec); 00252 } 00253 00254 int getProtocol() const { 00255 return m_protocol; 00256 } 00257 }; 00258 00260 // class stream_socket_stream 00262 00263 class stream_socket_stream : public basic_socket_stream { 00264 private: 00265 stream_socket_stream(const stream_socket_stream&); 00266 stream_socket_stream& operator=(const stream_socket_stream& socket); 00267 00268 protected: 00269 SOCKET_TYPE _connecting_socket; 00270 00271 stream_socket_stream(); 00272 stream_socket_stream(SOCKET_TYPE socket); 00273 public: 00274 virtual ~stream_socket_stream(); 00275 00276 virtual void close(); 00277 virtual SOCKET_TYPE getSocket() const; 00278 00279 bool connect_pending() const { 00280 return (_connecting_socket != INVALID_SOCKET); 00281 } 00282 }; 00283 00285 // class tcp_socket_stream 00287 00288 struct addrinfo; 00289 00291 class tcp_socket_stream : public stream_socket_stream { 00292 private: 00293 tcp_socket_stream(const tcp_socket_stream&); 00294 00295 tcp_socket_stream& operator=(const tcp_socket_stream& socket); 00296 00297 struct addrinfo * _connecting_address; 00298 struct addrinfo * _connecting_addrlist; 00299 00300 public: 00301 tcp_socket_stream(); 00302 tcp_socket_stream(SOCKET_TYPE socket); 00303 00304 tcp_socket_stream(const std::string& address, int service, 00305 bool nonblock = false); 00306 00307 tcp_socket_stream(const std::string& address, int service, 00308 unsigned int milliseconds); 00309 00310 virtual ~tcp_socket_stream(); 00311 00312 int open(const std::string& address, int service, bool nonblock = false); 00313 int open(const std::string& address, int service, unsigned int milliseconds); 00314 int open(struct addrinfo *, bool nonblock = false); 00315 int open_next(); 00316 00317 const std::string getRemoteHost(bool lookup = false) const; 00318 const std::string getRemoteService(bool lookup = false) const; 00319 bool isReady(unsigned int milliseconds = 0); 00320 }; 00321 00323 class dgram_socket_stream : public basic_socket_stream { 00324 private: 00325 dgram_socket_stream(const dgram_socket_stream&); 00326 00327 dgram_socket_stream& operator=(const dgram_socket_stream& socket); 00328 00329 protected: 00330 dgram_socketbuf & dgram_sockbuf; 00331 00332 int bindToIpService(int service, int type, int protocol); 00333 00334 public: 00335 dgram_socket_stream(); 00336 00337 virtual ~dgram_socket_stream(); 00338 00339 bool setTarget(const std::string& address, unsigned port) { 00340 return dgram_sockbuf.setTarget(address, port, m_protocol); 00341 } 00342 00343 void setOutpeer(const sockaddr_storage& peer) { 00344 return dgram_sockbuf.setOutpeer(peer); 00345 } 00346 00347 const sockaddr_storage & getOutpeer() const { 00348 return dgram_sockbuf.getOutpeer(); 00349 } 00350 00351 const sockaddr_storage & getInpeer() const { 00352 return dgram_sockbuf.getInpeer(); 00353 } 00354 00355 SOCKLEN getOutpeerSize() const { 00356 return dgram_sockbuf.getOutpeerSize(); 00357 } 00358 00359 SOCKLEN getInpeerSize() const { 00360 return dgram_sockbuf.getInpeerSize(); 00361 } 00362 }; 00363 00364 00366 // class udp_socket_stream 00368 00370 class udp_socket_stream : public dgram_socket_stream { 00371 private: 00372 udp_socket_stream(const udp_socket_stream&); 00373 00374 udp_socket_stream& operator=(const udp_socket_stream& socket); 00375 00376 public: 00377 udp_socket_stream(); 00378 00379 virtual ~udp_socket_stream(); 00380 00381 int open(int service); 00382 }; 00383 00384 #ifdef SOCK_RAW 00385 00387 // class raw_socket_stream 00389 00391 class raw_socket_stream : public dgram_socket_stream { 00392 private: 00393 raw_socket_stream(const raw_socket_stream&); 00394 00395 raw_socket_stream& operator=(const raw_socket_stream& socket); 00396 00397 public: 00398 raw_socket_stream(FreeSockets::IP_Protocol proto=FreeSockets::proto_RAW); 00399 00400 virtual ~raw_socket_stream(); 00401 00402 void setProtocol(FreeSockets::IP_Protocol proto); 00403 00404 bool setTarget(const std::string& address, unsigned port) { 00405 return dgram_sockbuf.setTarget(address, port, m_protocol); 00406 } 00407 00408 bool setBroadcast(bool opt=false); 00409 }; 00410 00411 #endif // SOCK_RAW 00412 00413 #endif // RGJ_FREE_STREAM_H_ 00414