GNU CommonC++
|
00001 // Copyright (C) 1999-2005 Open Source Telecom Corporation. 00002 // Copyright (C) 2006-2009 David Sugar, Tycho Softworks, 00003 // Copyright (C) 2009 Leandro Melo de Sales <leandroal@gmail.com> 00004 // 00005 // This program is free software; you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation; either version 2 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with this program; if not, write to the Free Software 00017 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00018 // 00019 // As a special exception, you may use this file as part of a free software 00020 // library without restriction. Specifically, if other files instantiate 00021 // templates or use macros or inline functions from this file, or you compile 00022 // this file and link it with other files to produce an executable, this 00023 // file does not by itself cause the resulting executable to be covered by 00024 // the GNU General Public License. This exception does not however 00025 // invalidate any other reasons why the executable file might be covered by 00026 // the GNU General Public License. 00027 // 00028 // This exception applies only to the code released under the name GNU 00029 // Common C++. If you copy code from other releases into a copy of GNU 00030 // Common C++, as the General Public License permits, the exception does 00031 // not apply to the code that you add in this way. To avoid misleading 00032 // anyone as to the status of such modified files, you must delete 00033 // this exception notice from them. 00034 // 00035 // If you write modifications of your own for GNU Common C++, it is your choice 00036 // whether to permit this exception to apply to your modifications. 00037 // If you do not wish that, delete this exception notice. 00038 // 00039 00045 #ifndef CCXX_SOCKET_H_ 00046 #define CCXX_SOCKET_H_ 00047 00048 #ifndef CCXX_ADDRESS_H_ 00049 #include <cc++/address.h> 00050 #endif 00051 00052 #if defined(WIN32) && !defined(__CYGWIN32__) 00053 #include <io.h> 00054 #define _IOLEN64 (unsigned) 00055 #define _IORET64 (int) 00056 #define TIMEOUT_INF ~((timeout_t) 0) 00057 typedef int socklen_t; 00058 #else 00059 #define INVALID_SOCKET -1 00060 typedef int SOCKET; 00061 #endif 00062 00063 #ifndef _IOLEN64 00064 #define _IOLEN64 00065 #endif 00066 00067 #ifndef _IORET64 00068 #define _IORET64 00069 #endif 00070 00071 #ifndef MSG_DONTWAIT 00072 #define MSG_DONTWAIT 0 00073 #endif 00074 00075 #ifndef MSG_NOSIGNAL 00076 #define MSG_NOSIGNAL 0 00077 #endif 00078 00079 #ifndef SOCK_DCCP 00080 #define SOCK_DCCP 6 00081 #endif 00082 #ifndef IPPROTO_DCCP 00083 #define IPPROTO_DCCP 33 00084 #endif 00085 #ifndef SOL_DCCP 00086 #define SOL_DCCP 269 00087 #endif 00088 #define DCCP_SOCKOPT_AVAILABLE_CCIDS 12 00089 #define DCCP_SOCKOPT_CCID 13 00090 #define DCCP_SOCKOPT_TX_CCID 14 00091 #define DCCP_SOCKOPT_RX_CCID 15 00092 00093 #ifdef CCXX_NAMESPACES 00094 namespace ost { 00095 #endif 00096 00100 typedef unsigned short tpport_t; 00101 00119 class __EXPORT Socket 00120 { 00121 public: 00122 enum Family { 00123 #ifdef CCXX_IPV6 00124 IPV6 = AF_INET6, 00125 #endif 00126 IPV4 = AF_INET 00127 }; 00128 00129 typedef enum Family Family; 00130 00131 enum Error { 00132 errSuccess = 0, 00133 errCreateFailed, 00134 errCopyFailed, 00135 errInput, 00136 errInputInterrupt, 00137 errResourceFailure, 00138 errOutput, 00139 errOutputInterrupt, 00140 errNotConnected, 00141 errConnectRefused, 00142 errConnectRejected, 00143 errConnectTimeout, 00144 errConnectFailed, 00145 errConnectInvalid, 00146 errConnectBusy, 00147 errConnectNoRoute, 00148 errBindingFailed, 00149 errBroadcastDenied, 00150 errRoutingDenied, 00151 errKeepaliveDenied, 00152 errServiceDenied, 00153 errServiceUnavailable, 00154 errMulticastDisabled, 00155 errTimeout, 00156 errNoDelay, 00157 errExtended, 00158 errLookupFail, 00159 errSearchErr, 00160 errInvalidValue 00161 }; 00162 00163 typedef enum Error Error; 00164 00165 enum Tos { 00166 tosLowDelay = 0, 00167 tosThroughput, 00168 tosReliability, 00169 tosMinCost, 00170 tosInvalid 00171 }; 00172 typedef enum Tos Tos; 00173 00174 enum Pending { 00175 pendingInput, 00176 pendingOutput, 00177 pendingError 00178 }; 00179 typedef enum Pending Pending; 00180 00181 protected: 00182 enum State { 00183 INITIAL, 00184 AVAILABLE, 00185 BOUND, 00186 CONNECTED, 00187 CONNECTING, 00188 STREAM 00189 }; 00190 typedef enum State State; 00191 00192 private: 00193 // used by exception handlers.... 00194 mutable Error errid; 00195 mutable const char *errstr; 00196 mutable long syserr; 00197 00198 void setSocket(void); 00199 friend SOCKET dupSocket(SOCKET s,Socket::State state); 00200 00201 protected: 00202 static Mutex mutex; 00203 00204 mutable struct { 00205 bool thrown: 1; 00206 bool broadcast: 1; 00207 bool route: 1; 00208 bool keepalive: 1; 00209 bool loopback: 1; 00210 bool multicast: 1; 00211 bool completion: 1; 00212 bool linger: 1; 00213 unsigned ttl: 8; 00214 } flags; 00215 00221 SOCKET volatile so; 00222 State volatile state; 00223 00232 Error error(Error error, const char *err = NULL, long systemError = 0) const; 00233 00240 inline void error(const char *err) const 00241 {error(errExtended, err);}; 00242 00249 inline void setError(bool enable) 00250 {flags.thrown = !enable;}; 00251 00257 void endSocket(void); 00258 00264 Error connectError(void); 00265 00269 Error sendLimit(int limit = 2048); 00270 00274 Error receiveLimit(int limit = 1); 00275 00282 Error sendTimeout(timeout_t timer); 00283 00290 Error receiveTimeout(timeout_t timer); 00291 00299 Error sendBuffer(unsigned size); 00300 00308 Error receiveBuffer(unsigned size); 00309 00317 Error bufferSize(unsigned size); 00318 00327 Error setBroadcast(bool enable); 00328 00340 Error setMulticastByFamily(bool enable, Family family = IPV4); 00341 00350 Error setLoopbackByFamily(bool enable, Family family = IPV4); 00351 00359 Error setTimeToLiveByFamily(unsigned char ttl, Family fam = IPV4); 00360 00367 Error join(const IPV4Multicast &ia); 00368 #ifdef CCXX_IPV6 00369 Error join(const IPV6Multicast &ia); 00370 #endif 00371 00378 Error drop(const IPV4Multicast &ia); 00379 #ifdef CCXX_IPV6 00380 Error drop(const IPV6Multicast &ia); 00381 #endif 00382 00390 Error setRouting(bool enable); 00391 00392 00399 Error setNoDelay(bool enable); 00400 00412 Socket(int domain, int type, int protocol = 0); 00413 00421 Socket(SOCKET fd); 00422 00426 Socket(); 00427 00435 Socket(const Socket &source); 00436 00446 ssize_t readLine(char *buf, size_t len, timeout_t timeout = 0); 00447 00459 virtual ssize_t readData(void * buf,size_t len,char separator=0,timeout_t t=0); 00460 00469 virtual ssize_t writeData(const void* buf,size_t len,timeout_t t=0); 00470 00471 public: 00479 virtual ~Socket(); 00480 00487 static bool check(Family fam); 00488 00492 Socket &operator=(const Socket &from); 00493 00503 IPV4Host getIPV4Sender(tpport_t *port = NULL) const; 00504 00505 inline IPV4Host getSender(tpport_t *port = NULL) const 00506 {return getIPV4Sender(port);} 00507 00508 #ifdef CCXX_IPV6 00509 IPV6Host getIPV6Sender(tpport_t *port = NULL) const; 00510 #endif 00511 00521 IPV4Host getIPV4Peer(tpport_t *port = NULL) const; 00522 00523 inline IPV4Host getPeer(tpport_t *port = NULL) const 00524 {return getIPV4Peer(port);} 00525 00526 #ifdef CCXX_IPV6 00527 IPV6Host getIPV6Peer(tpport_t *port = NULL) const; 00528 #endif 00529 00537 IPV4Host getIPV4Local(tpport_t *port = NULL) const; 00538 00539 inline IPV4Host getLocal(tpport_t *port = NULL) const 00540 {return getIPV4Local(port);} 00541 00542 #ifdef CCXX_IPV6 00543 IPV6Host getIPV6Local(tpport_t *port = NULL) const; 00544 #endif 00545 00573 IPV4Host getIPV4NAT(tpport_t *port = NULL) const; 00574 00575 inline IPV4Host getNAT(tpport_t *port) const 00576 {return getIPV4NAT(port);} 00577 00578 #ifdef CCXX_IPV6 00579 IPV6Host getIPV6NAT(tpport_t *port = NULL) const; 00580 #endif 00581 00592 void setCompletion(bool immediate); 00593 00599 Error setLinger(bool linger); 00600 00608 Error setKeepAlive(bool enable); 00609 00618 Error setTypeOfService(Tos service); 00619 00628 bool isConnected(void) const; 00629 00637 bool isActive(void) const; 00638 00643 bool operator!() const; 00644 00651 inline bool isBroadcast(void) const 00652 {return flags.broadcast;}; 00653 00659 inline bool isRouted(void) const 00660 {return flags.route;}; 00661 00668 inline Error getErrorNumber(void) const {return errid;} 00669 00676 inline const char *getErrorString(void) const {return errstr;} 00677 00678 inline long getSystemError(void) const {return syserr;} 00679 00680 const char *getSystemErrorString(void) const; 00681 00691 virtual bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF); 00692 }; 00693 00720 class __EXPORT DCCPSocket : public Socket 00721 { 00722 union { 00723 struct sockaddr_in ipv4; 00724 #ifdef CCXX_IPV6 00725 struct sockaddr_in6 ipv6; 00726 #endif 00727 } peer; 00728 00729 Family family; 00730 00731 public: 00743 virtual bool onAccept(const IPV4Host &ia, tpport_t port); 00744 #ifdef CCXX_IPV6 00745 virtual bool onAccept(const IPV6Host &ia, tpport_t port); 00746 #endif 00747 00759 DCCPSocket(const IPV4Address &bind, tpport_t port, unsigned backlog = 5); 00760 #ifdef CCXX_IPV6 00761 DCCPSocket(const IPV6Address &bind, tpport_t port, unsigned backlog = 5); 00762 #endif 00763 00773 DCCPSocket(const char *name, Family family = IPV4, unsigned backlog = 5); 00774 00778 DCCPSocket(Family family = IPV4); 00779 00783 DCCPSocket(DCCPSocket& server, timeout_t timeout = 0); 00784 00788 void reject(void); 00789 00793 void disconnect(void); 00794 00798 bool setCCID(uint8 ccid); 00799 00803 int getTxCCID(); 00804 00808 int getRxCCID(); 00809 00817 void connect(const IPV4Host &host, tpport_t port, timeout_t timeout = 0); 00818 #ifdef CCXX_IPV6 00819 void connect(const IPV6Host &host, tpport_t port, timeout_t timeout = 0); 00820 #endif 00821 00825 void connect(const char *name); 00826 00832 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF) /* not const -- jfc */ 00833 {return Socket::isPending(Socket::pendingInput, timeout);} 00834 00838 virtual ~DCCPSocket(); 00839 }; 00840 00873 class __EXPORT UDPSocket : public Socket 00874 { 00875 private: 00876 inline Error setKeepAlive(bool enable) 00877 {return Socket::setKeepAlive(enable);}; 00878 00879 protected: 00880 #ifdef CCXX_IPV6 00881 union { 00882 struct sockaddr_in6 ipv6; 00883 struct sockaddr_in ipv4; 00884 } peer; 00885 #else 00886 union { 00887 struct sockaddr_in ipv4; 00888 } peer; 00889 #endif 00890 00891 Family family; 00892 00893 public: 00897 UDPSocket(Family family = IPV4); 00898 00902 UDPSocket(const char *name, Family family = IPV4); 00903 00913 UDPSocket(const IPV4Address &bind, tpport_t port); 00914 #ifdef CCXX_IPV6 00915 UDPSocket(const IPV6Address &bind, tpport_t port); 00916 #endif 00917 00921 virtual ~UDPSocket(); 00922 00926 inline Error setLoopback(bool enable) 00927 {return Socket::setLoopbackByFamily(enable, family);} 00928 00932 inline Error setMulticast(bool enable) 00933 {return Socket::setMulticastByFamily(enable, family);} 00934 00938 inline Error setTimeToLive(char ttl) 00939 {return Socket::setTimeToLiveByFamily(ttl, family);} 00940 00948 void setPeer(const IPV4Host &host, tpport_t port); 00949 void connect(const IPV4Host &host, tpport_t port); 00950 #ifdef CCXX_IPV6 00951 void setPeer(const IPV6Host &host, tpport_t port); 00952 void connect(const IPV6Host &host, tpport_t port); 00953 #endif 00954 00962 Socket::Error getInterfaceIndex(const char *ethX,int& InterfaceIndex); 00963 00972 Socket::Error join(const IPV4Multicast &ia,int InterfaceIndex); 00973 00974 00982 ssize_t send(const void *buf, size_t len); 00983 00992 ssize_t receive(void *buf, size_t len, bool reply = false); 00993 01002 IPV4Host getIPV4Peer(tpport_t *port = NULL) const; 01003 inline IPV4Host getPeer(tpport_t *port = NULL) const 01004 {return getIPV4Peer(port);} 01005 01006 #ifdef CCXX_IPV6 01007 IPV6Host getIPV6Peer(tpport_t *port = NULL) const; 01008 #endif 01009 01017 inline ssize_t peek(void *buf, size_t len) 01018 {return _IORET64 ::recv(so, (char *)buf, _IOLEN64 len, MSG_PEEK);}; 01019 01023 void setPeer(const char *service); 01024 void connect(const char *service); 01025 01030 Error disconnect(void); 01031 }; 01032 01033 01042 class __EXPORT UDPBroadcast : public UDPSocket 01043 { 01044 private: 01045 void setPeer(const IPV4Host &ia, tpport_t port); 01046 01047 Error setBroadcast(bool enable) 01048 {return Socket::setBroadcast(enable);}; 01049 01050 public: 01057 UDPBroadcast(const IPV4Address &ia, tpport_t port); 01058 01065 void setPeer(const IPV4Broadcast &subnet, tpport_t port); 01066 }; 01067 01076 class __EXPORT UDPTransmit : protected UDPSocket 01077 { 01078 private: 01086 Error cConnect(const IPV4Address &ia, tpport_t port); 01087 01088 protected: 01092 UDPTransmit(Family family = IPV4); 01093 01105 UDPTransmit(const IPV4Address &bind, tpport_t port = 5005); 01106 #ifdef CCXX_IPV6 01107 UDPTransmit(const IPV6Address &bind, tpport_t port = 5005); 01108 #endif 01109 01119 Error connect(const IPV4Host &host, tpport_t port); 01120 #ifdef CCXX_IPV6 01121 Error connect(const IPV6Address &host, tpport_t port); 01122 #endif 01123 01133 Error connect(const IPV4Broadcast &subnet, tpport_t port); 01134 01142 Error connect(const IPV4Multicast &mgroup, tpport_t port); 01143 #ifdef CCXX_IPV6 01144 Error connect(const IPV6Multicast &mgroup, tpport_t port); 01145 #endif 01146 01154 inline ssize_t send(const void *buf, size_t len) 01155 {return _IORET64 ::send(so, (const char *)buf, _IOLEN64 len, MSG_NOSIGNAL);} 01156 01160 inline void endTransmitter(void) 01161 {Socket::endSocket();} 01162 01163 /* 01164 * Get transmitter socket. 01165 * 01166 * @return transmitter. 01167 */ 01168 inline SOCKET getTransmitter(void) 01169 {return so;}; 01170 01171 inline Error setMulticast(bool enable) 01172 {return Socket::setMulticastByFamily(enable, family);} 01173 01174 inline Error setTimeToLive(unsigned char ttl) 01175 {return Socket::setTimeToLiveByFamily(ttl, family);}; 01176 01177 public: 01187 inline ssize_t transmit(const char *buffer, size_t len) 01188 {return _IORET64 ::send(so, buffer, _IOLEN64 len, MSG_DONTWAIT|MSG_NOSIGNAL);} 01189 01196 inline bool isOutputReady(unsigned long timeout = 0l) 01197 {return Socket::isPending(Socket::pendingOutput, timeout);}; 01198 01199 01200 inline Error setRouting(bool enable) 01201 {return Socket::setRouting(enable);}; 01202 01203 inline Error setTypeOfService(Tos tos) 01204 {return Socket::setTypeOfService(tos);}; 01205 01206 inline Error setBroadcast(bool enable) 01207 {return Socket::setBroadcast(enable);}; 01208 }; 01209 01218 class __EXPORT UDPReceive : protected UDPSocket 01219 { 01220 protected: 01231 UDPReceive(const IPV4Address &bind, tpport_t port); 01232 #ifdef CCXX_IPV6 01233 UDPReceive(const IPV6Address &bind, tpport_t port); 01234 #endif 01235 01245 Error connect(const IPV4Host &host, tpport_t port); 01246 #ifdef CCXX_IPV6 01247 Error connect(const IPV6Host &host, tpport_t port); 01248 #endif 01249 01256 bool isPendingReceive(timeout_t timeout) 01257 {return Socket::isPending(Socket::pendingInput, timeout);}; 01258 01262 inline void endReceiver(void) 01263 {Socket::endSocket();} 01264 01265 inline SOCKET getReceiver(void) const 01266 {return so;}; 01267 01268 inline Error setRouting(bool enable) 01269 {return Socket::setRouting(enable);} 01270 01271 inline Error setMulticast(bool enable) 01272 {return Socket::setMulticastByFamily(enable, family);} 01273 01274 inline Error join(const IPV4Multicast &ia) 01275 {return Socket::join(ia);} 01276 01277 #ifdef CCXX_IPV6 01278 inline Error join(const IPV6Multicast &ia) 01279 {return Socket::join(ia);} 01280 #endif 01281 01282 inline Error drop(const IPV4Multicast &ia) 01283 {return Socket::drop(ia);} 01284 01285 #ifdef CCXX_IPV6 01286 inline Error drop(const IPV6Multicast &ia) 01287 {return Socket::drop(ia);} 01288 #endif 01289 01290 public: 01298 inline ssize_t receive(void *buf, size_t len) 01299 {return _IORET64 ::recv(so, (char *)buf, _IOLEN64 len, 0);}; 01300 01307 inline bool isInputReady(timeout_t timeout = TIMEOUT_INF) 01308 {return Socket::isPending(Socket::pendingInput, timeout);}; 01309 }; 01310 01321 class __EXPORT UDPDuplex : public UDPTransmit, public UDPReceive 01322 { 01323 public: 01331 UDPDuplex(const IPV4Address &bind, tpport_t port); 01332 #ifdef CCXX_IPV6 01333 UDPDuplex(const IPV6Address &bind, tpport_t port); 01334 #endif 01335 01345 Error connect(const IPV4Host &host, tpport_t port); 01346 #ifdef CCXX_IPV6 01347 Error connect(const IPV6Host &host, tpport_t port); 01348 #endif 01349 01356 Error disconnect(void); 01357 }; 01358 01359 01384 class __EXPORT TCPSocket : protected Socket 01385 { 01386 protected: 01387 int segsize; 01388 void setSegmentSize(unsigned mss); 01389 01390 public: 01402 virtual bool onAccept(const IPV4Host &ia, tpport_t port); 01403 01407 inline SOCKET getSocket(void) 01408 {return so;}; 01409 01413 inline int getSegmentSize(void) 01414 {return segsize;}; 01415 01428 TCPSocket(const IPV4Address &bind, tpport_t port, unsigned backlog = 5, unsigned mss = 536); 01429 01440 TCPSocket(const char *name, unsigned backlog = 5, unsigned mss = 536); 01441 01450 inline IPV4Host getRequest(tpport_t *port = NULL) const 01451 {return Socket::getIPV4Sender(port);} 01452 01456 void reject(void); 01457 01461 inline IPV4Host getLocal(tpport_t *port = NULL) const 01462 {return Socket::getIPV4Local(port);} 01463 01469 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF) /* not const -- jfc */ 01470 {return Socket::isPending(Socket::pendingInput, timeout);} 01471 01475 virtual ~TCPSocket(); 01476 }; 01477 01478 #ifdef CCXX_IPV6 01479 01503 class __EXPORT TCPV6Socket : protected Socket 01504 { 01505 private: 01506 int segsize; 01507 void setSegmentSize(unsigned mss); 01508 01509 public: 01521 virtual bool onAccept(const IPV6Host &ia, tpport_t port); 01522 01526 inline SOCKET getSocket(void) 01527 {return so;}; 01528 01529 inline int getSegmentSize(void) 01530 {return segsize;}; 01531 01544 TCPV6Socket(const IPV6Address &bind, tpport_t port, unsigned backlog = 5, unsigned mss = 536); 01545 01556 TCPV6Socket(const char *name, unsigned backlog = 5, unsigned mss = 536); 01557 01566 inline IPV6Host getRequest(tpport_t *port = NULL) const 01567 {return Socket::getIPV6Sender(port);} 01568 01572 void reject(void); 01573 01577 inline IPV6Host getLocal(tpport_t *port = NULL) const 01578 {return Socket::getIPV6Local(port);} 01579 01585 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF) /* not const -- jfc */ 01586 {return Socket::isPending(Socket::pendingInput, timeout);} 01587 01591 virtual ~TCPV6Socket(); 01592 }; 01593 01594 #endif 01595 01596 /* 01597 :\projects\libraries\cplusplus\commonc++\win32\socket.h(357) : warning C4275: non dll-interface class 'streambuf' used as base for dll-interface class 'TCPStream' 01598 c:\program files\microsoft visual studio\vc98\include\streamb.h(69) : see declaration of 'streambuf' 01599 c:\projects\libraries\cplusplus\commonc++\win32\socket.h(358) : warning C4275: non dll-interface class 'iostream' used as base for dll-interface class 'TCPStream' 01600 c:\program files\microsoft visual studio\vc98\include\iostream.h(66) : see declaration of 'iostream' 01601 */ 01602 01603 #ifdef _MSC_VER 01604 #pragma warning(disable:4275) // disable C4275 warning 01605 #endif 01606 01620 class __EXPORT TCPStream : protected std::streambuf, public Socket, public std::iostream 01621 { 01622 private: 01623 int doallocate(); 01624 01625 void segmentBuffering(unsigned mss); 01626 01627 friend TCPStream& crlf(TCPStream&); 01628 friend TCPStream& lfcr(TCPStream&); 01629 01630 protected: 01631 timeout_t timeout; 01632 size_t bufsize; 01633 Family family; 01634 char *gbuf, *pbuf; 01635 01636 public: 01641 TCPStream(Family family = IPV4, bool throwflag = true, timeout_t to = 0); 01642 01646 void disconnect(void); 01647 01651 int getSegmentSize(void); 01652 01653 protected: 01660 void allocate(size_t size); 01661 01666 void endStream(void); 01667 01674 int underflow(); 01675 01684 int uflow(); 01685 01693 int overflow(int ch); 01694 01703 void connect(const IPV4Host &host, tpport_t port, unsigned mss = 536); 01704 #ifdef CCXX_IPV6 01705 void connect(const IPV6Host &host, tpport_t port, unsigned mss = 536); 01706 #endif 01707 01715 void connect(const char *name, unsigned mss = 536); 01716 01724 std::iostream *tcp(void) 01725 {return ((std::iostream *)this);}; 01726 01727 public: 01737 TCPStream(TCPSocket &server, bool throwflag = true, timeout_t timeout = 0); 01738 #ifdef CCXX_IPV6 01739 TCPStream(TCPV6Socket &server, bool throwflag = true, timeout_t timeout = 0); 01740 #endif 01741 01747 void connect(TCPSocket &server); 01748 #ifdef CCXX_IPV6 01749 void connect(TCPV6Socket &server); 01750 #endif 01751 01762 TCPStream(const IPV4Host &host, tpport_t port, unsigned mss = 536, bool throwflag = true, timeout_t timeout = 0); 01763 #ifdef CCXX_IPV6 01764 TCPStream(const IPV6Host &host, tpport_t port, unsigned mss = 536, bool throwflag = true, timeout_t timeout = 0); 01765 #endif 01766 01776 TCPStream(const char *name, Family family = IPV4, unsigned mss = 536, bool throwflag = false, timeout_t timer = 0); 01777 01783 inline void setTimeout(timeout_t timer) 01784 {timeout = timer;}; 01785 01792 TCPStream(const TCPStream &source); 01793 01798 virtual ~TCPStream(); 01799 01806 int sync(void); 01807 01808 #ifdef HAVE_SNPRINTF 01809 01815 size_t printf(const char *format, ...); 01816 #endif 01817 01825 bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF); 01826 01834 inline ssize_t peek(void *buf, size_t len) 01835 {return _IORET64 ::recv(so, (char *)buf, _IOLEN64 len, MSG_PEEK);}; 01836 01842 inline size_t getBufferSize(void) const 01843 {return bufsize;}; 01844 }; 01845 01856 class __EXPORT TCPSession : public Thread, public TCPStream 01857 { 01858 private: 01859 TCPSession(const TCPSession &rhs); // not defined 01860 protected: 01873 int waitConnection(timeout_t timeout = TIMEOUT_INF); 01874 01881 void initial(void); 01882 01883 public: 01894 TCPSession(const IPV4Host &host, 01895 tpport_t port, size_t size = 536, int pri = 0, size_t stack = 0); 01896 #ifdef CCXX_IPV6 01897 TCPSession(const IPV6Host &host, 01898 tpport_t port, size_t size = 536, int pri = 0, size_t stack = 0); 01899 #endif 01900 01910 TCPSession(TCPSocket &server, int pri = 0, size_t stack = 0); 01911 #ifdef CCXX_IPV6 01912 TCPSession(TCPV6Socket &server, int pri = 0, size_t stack = 0); 01913 #endif 01914 01918 virtual ~TCPSession(); 01919 }; 01920 01921 #if defined(WIN32) 01922 01932 class init_WSA 01933 { 01934 public: 01935 init_WSA(); 01936 ~init_WSA(); 01937 }; 01938 01939 #endif // WIN32 01940 01941 class __EXPORT SimpleTCPStream; 01942 01954 class __EXPORT SimpleTCPStream : public Socket 01955 { 01956 private: 01957 01958 IPV4Host getSender(tpport_t *port) const; 01959 01960 protected: 01965 SimpleTCPStream(); 01966 01971 void endStream(void); 01972 01981 void Connect(const IPV4Host &host, tpport_t port, size_t size); 01982 01983 01984 public: 01993 SimpleTCPStream(TCPSocket &server, size_t size = 512); 01994 02003 SimpleTCPStream(const IPV4Host &host, tpport_t port, size_t size = 512); 02004 02010 SimpleTCPStream(const SimpleTCPStream &source); 02011 02016 virtual ~SimpleTCPStream(); 02017 02029 bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF); 02030 02031 void flush() {} 02032 02044 ssize_t read(char *bytes, size_t length, timeout_t timeout = 0); 02045 02057 ssize_t write(const char *bytes, size_t length, timeout_t timeout = 0); 02058 02072 ssize_t peek(char *bytes, size_t length, timeout_t timeout = 0); 02073 02074 }; 02075 02076 #ifdef COMMON_STD_EXCEPTION 02077 class __EXPORT SockException : public IOException 02078 { 02079 private: 02080 Socket::Error _socketError; 02081 02082 public: 02083 SockException(const String &str, Socket::Error socketError, long systemError = 0) : 02084 IOException(str, systemError), _socketError(socketError) {}; 02085 02086 inline Socket::Error getSocketError() const 02087 { return _socketError; } 02088 }; 02089 #endif 02090 02091 #ifdef CCXX_NAMESPACES 02092 } 02093 #endif 02094 02095 #endif 02096