GNU CommonC++

socket.h

Go to the documentation of this file.
00001 // Copyright (C) 1999-2005 Open Source Telecom Corporation.
00002 // Copyright (C) 2009 Leandro Melo de Sales <leandroal@gmail.com>
00003 // Copyright (C) 2006-2010 David Sugar, Tycho Softworks,
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     virtual 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     virtual 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 
00748     virtual IPV4Host getIPV4Sender(tpport_t *port = NULL) const;
00749 
00750 #ifdef  CCXX_IPV6
00751     virtual IPV6Host getIPV6Sender(tpport_t *port = NULL) const;
00752 #endif
00753 
00765     DCCPSocket(const IPV4Address &bind, tpport_t port, unsigned backlog = 5);
00766 #ifdef  CCXX_IPV6
00767     DCCPSocket(const IPV6Address &bind, tpport_t port, unsigned backlog = 5);
00768 #endif
00769 
00779     DCCPSocket(const char *name, Family family = IPV4, unsigned backlog = 5);
00780 
00784     DCCPSocket(Family family = IPV4);
00785 
00789     DCCPSocket(DCCPSocket& server, timeout_t timeout = 0);
00790 
00794     void reject(void);
00795 
00799     void disconnect(void);
00800 
00804     bool setCCID(uint8 ccid);
00805 
00809     int getTxCCID();
00810 
00814     int getRxCCID();
00815 
00819     size_t available();
00820 
00828     void connect(const IPV4Host &host, tpport_t port, timeout_t timeout = 0);
00829 #ifdef  CCXX_IPV6
00830     void connect(const IPV6Host &host, tpport_t port, timeout_t timeout = 0);
00831 #endif
00832 
00836     void connect(const char *name);
00837 
00843     inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF) /* not const -- jfc */
00844         {return Socket::isPending(Socket::pendingInput, timeout);}
00845 
00849     virtual ~DCCPSocket();
00850 };
00851 
00884 class __EXPORT UDPSocket : public Socket
00885 {
00886 private:
00887     inline Error setKeepAlive(bool enable)
00888         {return Socket::setKeepAlive(enable);};
00889 
00890 protected:
00891 #ifdef  CCXX_IPV6
00892     union {
00893         struct sockaddr_in6 ipv6;
00894         struct sockaddr_in ipv4;
00895     }   peer;
00896 #else
00897     union {
00898         struct sockaddr_in ipv4;
00899     }   peer;
00900 #endif
00901 
00902     Family family;
00903 
00904 public:
00908     UDPSocket(Family family = IPV4);
00909 
00913     UDPSocket(const char *name, Family family = IPV4);
00914 
00924     UDPSocket(const IPV4Address &bind, tpport_t port);
00925 #ifdef  CCXX_IPV6
00926     UDPSocket(const IPV6Address &bind, tpport_t port);
00927 #endif
00928 
00932     virtual ~UDPSocket();
00933 
00937     inline Error setLoopback(bool enable)
00938         {return Socket::setLoopbackByFamily(enable, family);}
00939 
00943     inline Error setMulticast(bool enable)
00944         {return Socket::setMulticastByFamily(enable, family);}
00945 
00949     inline Error setTimeToLive(char ttl)
00950         {return Socket::setTimeToLiveByFamily(ttl, family);}
00951 
00959     void setPeer(const IPV4Host &host, tpport_t port);
00960     void connect(const IPV4Host &host, tpport_t port);
00961 #ifdef  CCXX_IPV6
00962     void setPeer(const IPV6Host &host, tpport_t port);
00963     void connect(const IPV6Host &host, tpport_t port);
00964 #endif
00965 
00973     Socket::Error getInterfaceIndex(const char *ethX,int& InterfaceIndex);
00974 
00983     Socket::Error join(const IPV4Multicast &ia,int InterfaceIndex);
00984 
00985 
00993     ssize_t send(const void *buf, size_t len);
00994 
01003     ssize_t receive(void *buf, size_t len, bool reply = false);
01004 
01013     IPV4Host getIPV4Peer(tpport_t *port = NULL) const;
01014     inline IPV4Host getPeer(tpport_t *port = NULL) const
01015         {return getIPV4Peer(port);}
01016 
01017 #ifdef  CCXX_IPV6
01018     IPV6Host getIPV6Peer(tpport_t *port = NULL) const;
01019 #endif
01020 
01028     inline ssize_t peek(void *buf, size_t len)
01029         {return _IORET64 ::recv(so, (char *)buf, _IOLEN64 len, MSG_PEEK);};
01030 
01034     void setPeer(const char *service);
01035     void connect(const char *service);
01036 
01041     Error disconnect(void);
01042 };
01043 
01044 
01053 class __EXPORT UDPBroadcast : public UDPSocket
01054 {
01055 private:
01056     void setPeer(const IPV4Host &ia, tpport_t port);
01057 
01058     Error setBroadcast(bool enable)
01059         {return Socket::setBroadcast(enable);};
01060 
01061 public:
01068     UDPBroadcast(const IPV4Address &ia, tpport_t port);
01069 
01076     void setPeer(const IPV4Broadcast &subnet, tpport_t port);
01077 };
01078 
01087 class __EXPORT UDPTransmit : protected UDPSocket
01088 {
01089 private:
01097     Error cConnect(const IPV4Address &ia, tpport_t port);
01098 
01099 protected:
01103     UDPTransmit(Family family = IPV4);
01104 
01116     UDPTransmit(const IPV4Address &bind, tpport_t port = 5005);
01117 #ifdef  CCXX_IPV6
01118     UDPTransmit(const IPV6Address &bind, tpport_t port = 5005);
01119 #endif
01120 
01130     Error connect(const IPV4Host &host, tpport_t port);
01131 #ifdef  CCXX_IPV6
01132     Error connect(const IPV6Address &host, tpport_t port);
01133 #endif
01134 
01144     Error connect(const IPV4Broadcast &subnet, tpport_t port);
01145 
01153     Error connect(const IPV4Multicast &mgroup, tpport_t port);
01154 #ifdef  CCXX_IPV6
01155     Error connect(const IPV6Multicast &mgroup, tpport_t port);
01156 #endif
01157 
01165     inline ssize_t send(const void *buf, size_t len)
01166         {return _IORET64 ::send(so, (const char *)buf, _IOLEN64 len, MSG_NOSIGNAL);}
01167 
01171     inline void endTransmitter(void)
01172         {Socket::endSocket();}
01173 
01174     /*
01175      * Get transmitter socket.
01176      *
01177      * @return transmitter.
01178      */
01179     inline SOCKET getTransmitter(void)
01180         {return so;};
01181 
01182     inline Error setMulticast(bool enable)
01183         {return Socket::setMulticastByFamily(enable, family);}
01184 
01185     inline Error setTimeToLive(unsigned char ttl)
01186         {return Socket::setTimeToLiveByFamily(ttl, family);};
01187 
01188 public:
01198     inline ssize_t transmit(const char *buffer, size_t len)
01199         {return _IORET64 ::send(so, buffer, _IOLEN64 len, MSG_DONTWAIT|MSG_NOSIGNAL);}
01200 
01207     inline bool isOutputReady(unsigned long timeout = 0l)
01208         {return Socket::isPending(Socket::pendingOutput, timeout);};
01209 
01210 
01211     inline Error setRouting(bool enable)
01212         {return Socket::setRouting(enable);};
01213 
01214     inline Error setTypeOfService(Tos tos)
01215         {return Socket::setTypeOfService(tos);};
01216 
01217     inline Error setBroadcast(bool enable)
01218         {return Socket::setBroadcast(enable);};
01219 };
01220 
01229 class __EXPORT UDPReceive : protected UDPSocket
01230 {
01231 protected:
01242     UDPReceive(const IPV4Address &bind, tpport_t port);
01243 #ifdef  CCXX_IPV6
01244     UDPReceive(const IPV6Address &bind, tpport_t port);
01245 #endif
01246 
01256     Error connect(const IPV4Host &host, tpport_t port);
01257 #ifdef  CCXX_IPV6
01258     Error connect(const IPV6Host &host, tpport_t port);
01259 #endif
01260 
01267     bool isPendingReceive(timeout_t timeout)
01268         {return Socket::isPending(Socket::pendingInput, timeout);};
01269 
01273     inline void endReceiver(void)
01274         {Socket::endSocket();}
01275 
01276     inline SOCKET getReceiver(void) const
01277         {return so;};
01278 
01279     inline Error setRouting(bool enable)
01280         {return Socket::setRouting(enable);}
01281 
01282     inline Error setMulticast(bool enable)
01283         {return Socket::setMulticastByFamily(enable, family);}
01284 
01285     inline Error join(const IPV4Multicast &ia)
01286             {return Socket::join(ia);}
01287 
01288 #ifdef  CCXX_IPV6
01289     inline Error join(const IPV6Multicast &ia)
01290         {return Socket::join(ia);}
01291 #endif
01292 
01293     inline Error drop(const IPV4Multicast &ia)
01294             {return Socket::drop(ia);}
01295 
01296 #ifdef  CCXX_IPV6
01297     inline Error drop(const IPV6Multicast &ia)
01298         {return Socket::drop(ia);}
01299 #endif
01300 
01301 public:
01309     inline ssize_t receive(void *buf, size_t len)
01310         {return _IORET64 ::recv(so, (char *)buf, _IOLEN64 len, 0);};
01311 
01318     inline bool isInputReady(timeout_t timeout = TIMEOUT_INF)
01319         {return Socket::isPending(Socket::pendingInput, timeout);};
01320 };
01321 
01332 class __EXPORT UDPDuplex : public UDPTransmit, public UDPReceive
01333 {
01334 public:
01342     UDPDuplex(const IPV4Address &bind, tpport_t port);
01343 #ifdef  CCXX_IPV6
01344     UDPDuplex(const IPV6Address &bind, tpport_t port);
01345 #endif
01346 
01356     Error connect(const IPV4Host &host, tpport_t port);
01357 #ifdef  CCXX_IPV6
01358     Error connect(const IPV6Host &host, tpport_t port);
01359 #endif
01360 
01367     Error disconnect(void);
01368 };
01369 
01370 
01395 class __EXPORT TCPSocket : protected Socket
01396 {
01397 protected:
01398     int segsize;
01399     void setSegmentSize(unsigned mss);
01400 
01401 public:
01413     virtual bool onAccept(const IPV4Host &ia, tpport_t port);
01414 
01418     inline SOCKET getSocket(void)
01419         {return so;};
01420 
01424     inline int getSegmentSize(void)
01425         {return segsize;};
01426 
01439     TCPSocket(const IPV4Address &bind, tpport_t port, unsigned backlog = 5, unsigned mss = 536);
01440 
01451     TCPSocket(const char *name, unsigned backlog = 5, unsigned mss = 536);
01452 
01461     inline IPV4Host getRequest(tpport_t *port = NULL) const
01462         {return Socket::getIPV4Sender(port);}
01463 
01467     void reject(void);
01468 
01472     inline IPV4Host getLocal(tpport_t *port = NULL) const
01473         {return Socket::getIPV4Local(port);}
01474 
01480     inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF) /* not const -- jfc */
01481         {return Socket::isPending(Socket::pendingInput, timeout);}
01482 
01486     virtual ~TCPSocket();
01487 };
01488 
01489 #ifdef  CCXX_IPV6
01490 
01514 class __EXPORT TCPV6Socket : protected Socket
01515 {
01516 private:
01517     int segsize;
01518     void setSegmentSize(unsigned mss);
01519 
01520 public:
01532     virtual bool onAccept(const IPV6Host &ia, tpport_t port);
01533 
01537     inline SOCKET getSocket(void)
01538         {return so;};
01539 
01540     inline int getSegmentSize(void)
01541         {return segsize;};
01542 
01555     TCPV6Socket(const IPV6Address &bind, tpport_t port, unsigned backlog = 5, unsigned mss = 536);
01556 
01567     TCPV6Socket(const char *name, unsigned backlog = 5, unsigned mss = 536);
01568 
01577     inline IPV6Host getRequest(tpport_t *port = NULL) const
01578         {return Socket::getIPV6Sender(port);}
01579 
01583     void reject(void);
01584 
01588     inline IPV6Host getLocal(tpport_t *port = NULL) const
01589         {return Socket::getIPV6Local(port);}
01590 
01596     inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF) /* not const -- jfc */
01597         {return Socket::isPending(Socket::pendingInput, timeout);}
01598 
01602     virtual ~TCPV6Socket();
01603 };
01604 
01605 #endif
01606 
01607 /*
01608 :\projects\libraries\cplusplus\commonc++\win32\socket.h(357) : warning C4275: non dll-interface class 'streambuf' used as base for dll-interface class 'TCPStream'
01609     c:\program files\microsoft visual studio\vc98\include\streamb.h(69) : see declaration of 'streambuf'
01610 c:\projects\libraries\cplusplus\commonc++\win32\socket.h(358) : warning C4275: non dll-interface class 'iostream' used as base for dll-interface class 'TCPStream'
01611     c:\program files\microsoft visual studio\vc98\include\iostream.h(66) : see declaration of 'iostream'
01612 */
01613 
01614 #ifdef _MSC_VER
01615 #pragma warning(disable:4275) // disable C4275 warning
01616 #endif
01617 
01631 class __EXPORT TCPStream : protected std::streambuf, public Socket, public std::iostream
01632 {
01633 private:
01634     int doallocate();
01635 
01636     void segmentBuffering(unsigned mss);
01637 
01638     friend TCPStream& crlf(TCPStream&);
01639     friend TCPStream& lfcr(TCPStream&);
01640 
01641 protected:
01642     timeout_t timeout;
01643     size_t bufsize;
01644     Family family;
01645     char *gbuf, *pbuf;
01646 
01647 public:
01652     TCPStream(Family family = IPV4, bool throwflag = true, timeout_t to = 0);
01653 
01657     void disconnect(void);
01658 
01662     int getSegmentSize(void);
01663 
01664 protected:
01671     void allocate(size_t size);
01672 
01677     void endStream(void);
01678 
01685     int underflow();
01686 
01695     int uflow();
01696 
01704     int overflow(int ch);
01705 
01714     void connect(const IPV4Host &host, tpport_t port, unsigned mss = 536);
01715 #ifdef  CCXX_IPV6
01716     void connect(const IPV6Host &host, tpport_t port, unsigned mss = 536);
01717 #endif
01718 
01726     void connect(const char *name, unsigned mss = 536);
01727 
01735     std::iostream *tcp(void)
01736         {return ((std::iostream *)this);};
01737 
01738 public:
01748     TCPStream(TCPSocket &server, bool throwflag = true, timeout_t timeout = 0);
01749 #ifdef  CCXX_IPV6
01750     TCPStream(TCPV6Socket &server, bool throwflag = true, timeout_t timeout = 0);
01751 #endif
01752 
01758     void connect(TCPSocket &server);
01759 #ifdef  CCXX_IPV6
01760     void connect(TCPV6Socket &server);
01761 #endif
01762 
01773     TCPStream(const IPV4Host &host, tpport_t port, unsigned mss = 536, bool throwflag = true, timeout_t timeout = 0);
01774 #ifdef  CCXX_IPV6
01775     TCPStream(const IPV6Host &host, tpport_t port, unsigned mss = 536, bool throwflag = true, timeout_t timeout = 0);
01776 #endif
01777 
01787     TCPStream(const char *name, Family family = IPV4, unsigned mss = 536, bool throwflag = false, timeout_t timer = 0);
01788 
01794     inline void setTimeout(timeout_t timer)
01795         {timeout = timer;};
01796 
01803     TCPStream(const TCPStream &source);
01804 
01809     virtual ~TCPStream();
01810 
01817     int sync(void);
01818 
01819 #ifdef  HAVE_SNPRINTF
01820 
01826     size_t printf(const char *format, ...);
01827 #endif
01828 
01836     bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
01837 
01845      inline ssize_t peek(void *buf, size_t len)
01846          {return _IORET64 ::recv(so, (char *)buf, _IOLEN64 len, MSG_PEEK);};
01847 
01853     inline size_t getBufferSize(void) const
01854         {return bufsize;};
01855 };
01856 
01867 class __EXPORT TCPSession : public Thread, public TCPStream
01868 {
01869 private:
01870     TCPSession(const TCPSession &rhs); // not defined
01871 protected:
01884     int waitConnection(timeout_t timeout = TIMEOUT_INF);
01885 
01892     void initial(void);
01893 
01894 public:
01905     TCPSession(const IPV4Host &host,
01906         tpport_t port, size_t size = 536, int pri = 0, size_t stack = 0);
01907 #ifdef  CCXX_IPV6
01908     TCPSession(const IPV6Host &host,
01909         tpport_t port, size_t size = 536, int pri = 0, size_t stack = 0);
01910 #endif
01911 
01921     TCPSession(TCPSocket &server, int pri = 0, size_t stack = 0);
01922 #ifdef  CCXX_IPV6
01923     TCPSession(TCPV6Socket &server, int pri = 0, size_t stack = 0);
01924 #endif
01925 
01929     virtual ~TCPSession();
01930 };
01931 
01932 #if defined(WIN32)
01933 
01943 class init_WSA
01944 {
01945 public:
01946     init_WSA();
01947     ~init_WSA();
01948 };
01949 
01950 #endif // WIN32
01951 
01952 class __EXPORT SimpleTCPStream;
01953 
01965 class __EXPORT SimpleTCPStream : public Socket
01966 {
01967 private:
01968 
01969     IPV4Host getSender(tpport_t *port) const;
01970 
01971 protected:
01976     SimpleTCPStream();
01977 
01982     void endStream(void);
01983 
01992     void Connect(const IPV4Host &host, tpport_t port, size_t size);
01993 
01994 
01995 public:
02004     SimpleTCPStream(TCPSocket &server, size_t size = 512);
02005 
02014     SimpleTCPStream(const IPV4Host &host, tpport_t port, size_t size = 512);
02015 
02021     SimpleTCPStream(const SimpleTCPStream &source);
02022 
02027     virtual ~SimpleTCPStream();
02028 
02040     bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
02041 
02042     void flush() {}
02043 
02055     ssize_t read(char *bytes, size_t length, timeout_t timeout = 0);
02056 
02068     ssize_t write(const char *bytes, size_t length, timeout_t timeout = 0);
02069 
02083     ssize_t peek(char *bytes, size_t length, timeout_t timeout = 0);
02084 
02085 };
02086 
02087 #ifdef  COMMON_STD_EXCEPTION
02088 class __EXPORT SockException : public IOException
02089 {
02090 private:
02091     Socket::Error _socketError;
02092 
02093 public:
02094     SockException(const String &str, Socket::Error socketError, long systemError = 0) :
02095         IOException(str, systemError), _socketError(socketError) {};
02096 
02097     inline Socket::Error getSocketError() const
02098     { return _socketError; }
02099 };
02100 #endif
02101 
02102 #ifdef  CCXX_NAMESPACES
02103 }
02104 #endif
02105 
02106 #endif
02107