00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00043 #ifndef CCXX_SOCKET_H_
00044 #define CCXX_SOCKET_H_
00045
00046 #ifndef CCXX_ADDRESS_H_
00047 #include <cc++/address.h>
00048 #endif
00049
00050 #if defined(WIN32) && !defined(__CYGWIN32__)
00051 #include <io.h>
00052 #define _IOLEN64 (unsigned)
00053 #define _IORET64 (int)
00054 #define TIMEOUT_INF ~((timeout_t) 0)
00055 typedef int socklen_t;
00056 #else
00057 #define INVALID_SOCKET -1
00058 typedef int SOCKET;
00059 #endif
00060
00061 #ifndef _IOLEN64
00062 #define _IOLEN64
00063 #endif
00064
00065 #ifndef _IORET64
00066 #define _IORET64
00067 #endif
00068
00069 #ifndef MSG_DONTWAIT
00070 #define MSG_DONTWAIT 0
00071 #endif
00072
00073 #ifdef CCXX_NAMESPACES
00074 namespace ost {
00075 #endif
00076
00080 typedef unsigned short tpport_t;
00081
00099 class __EXPORT Socket
00100 {
00101 public:
00102 enum Family
00103 {
00104 #ifdef CCXX_IPV6
00105 IPV6 = AF_INET6,
00106 #endif
00107 IPV4 = AF_INET
00108 };
00109
00110 typedef enum Family Family;
00111
00112 enum Error
00113 {
00114 errSuccess = 0,
00115 errCreateFailed,
00116 errCopyFailed,
00117 errInput,
00118 errInputInterrupt,
00119 errResourceFailure,
00120 errOutput,
00121 errOutputInterrupt,
00122 errNotConnected,
00123 errConnectRefused,
00124 errConnectRejected,
00125 errConnectTimeout,
00126 errConnectFailed,
00127 errConnectInvalid,
00128 errConnectBusy,
00129 errConnectNoRoute,
00130 errBindingFailed,
00131 errBroadcastDenied,
00132 errRoutingDenied,
00133 errKeepaliveDenied,
00134 errServiceDenied,
00135 errServiceUnavailable,
00136 errMulticastDisabled,
00137 errTimeout,
00138 errNoDelay,
00139 errExtended,
00140 errLookupFail,
00141 errSearchErr,
00142 errInvalidValue
00143 };
00144
00145 typedef enum Error Error;
00146
00147 enum Tos
00148 {
00149 tosLowDelay = 0,
00150 tosThroughput,
00151 tosReliability,
00152 tosMinCost,
00153 tosInvalid
00154 };
00155 typedef enum Tos Tos;
00156
00157 enum Pending
00158 {
00159 pendingInput,
00160 pendingOutput,
00161 pendingError
00162 };
00163 typedef enum Pending Pending;
00164
00165 protected:
00166 enum State
00167 {
00168 INITIAL,
00169 AVAILABLE,
00170 BOUND,
00171 CONNECTED,
00172 CONNECTING,
00173 STREAM
00174 };
00175 typedef enum State State;
00176
00177 private:
00178
00179 mutable Error errid;
00180 mutable const char *errstr;
00181 mutable long syserr;
00182
00183 void setSocket(void);
00184 friend SOCKET dupSocket(SOCKET s,Socket::State state);
00185
00186 protected:
00187 static Mutex mutex;
00188
00189 mutable struct
00190 {
00191 bool thrown: 1;
00192 bool broadcast: 1;
00193 bool route: 1;
00194 bool keepalive: 1;
00195 bool loopback: 1;
00196 bool multicast: 1;
00197 bool completion: 1;
00198 bool linger: 1;
00199 unsigned ttl: 8;
00200 } flags;
00201
00207 SOCKET volatile so;
00208 State volatile state;
00209
00218 Error error(Error error, char *err = NULL, long systemError = 0) const;
00219
00226 inline void error(char *err) const
00227 {error(errExtended, err);};
00228
00235 inline void setError(bool enable)
00236 {flags.thrown = !enable;};
00237
00243 void endSocket(void);
00244
00250 Error connectError(void);
00251
00255 Error sendLimit(int limit = 2048);
00256
00260 Error receiveLimit(int limit = 1);
00261
00268 Error sendTimeout(timeout_t timer);
00269
00276 Error receiveTimeout(timeout_t timer);
00277
00285 Error sendBuffer(unsigned size);
00286
00294 Error receiveBuffer(unsigned size);
00295
00303 Error bufferSize(unsigned size);
00304
00313 Error setBroadcast(bool enable);
00314
00326 Error setMulticastByFamily(bool enable, Family family = IPV4);
00327
00336 Error setLoopbackByFamily(bool enable, Family family = IPV4);
00337
00345 Error setTimeToLiveByFamily(unsigned char ttl, Family fam = IPV4);
00346
00353 Error join(const IPV4Multicast &ia);
00354 #ifdef CCXX_IPV6
00355 Error join(const IPV6Multicast &ia);
00356 #endif
00357
00364 Error drop(const IPV4Multicast &ia);
00365 #ifdef CCXX_IPV6
00366 Error drop(const IPV6Multicast &ia);
00367 #endif
00368
00376 Error setRouting(bool enable);
00377
00378
00385 Error setNoDelay(bool enable);
00386
00398 Socket(int domain, int type, int protocol = 0);
00399
00407 Socket(SOCKET fd);
00408
00412 Socket();
00413
00421 Socket(const Socket &source);
00422
00432 ssize_t readLine(char *buf, size_t len, timeout_t timeout = 0);
00433
00445 virtual ssize_t readData(void * buf,size_t len,char separator=0,timeout_t t=0);
00446
00455 virtual ssize_t writeData(const void* buf,size_t len,timeout_t t=0);
00456
00457 public:
00465 virtual ~Socket();
00466
00473 static bool check(Family fam);
00474
00478 Socket &operator=(const Socket &from);
00479
00489 IPV4Host getIPV4Sender(tpport_t *port = NULL) const;
00490
00491 inline IPV4Host getSender(tpport_t *port = NULL) const
00492 {return getIPV4Sender(port);}
00493
00494 #ifdef CCXX_IPV6
00495 IPV6Host getIPV6Sender(tpport_t *port = NULL) const;
00496 #endif
00497
00507 IPV4Host getIPV4Peer(tpport_t *port = NULL) const;
00508
00509 inline IPV4Host getPeer(tpport_t *port = NULL) const
00510 {return getIPV4Peer(port);}
00511
00512 #ifdef CCXX_IPV6
00513 IPV6Host getIPV6Peer(tpport_t *port = NULL) const;
00514 #endif
00515
00523 IPV4Host getIPV4Local(tpport_t *port = NULL) const;
00524
00525 inline IPV4Host getLocal(tpport_t *port = NULL) const
00526 {return getIPV4Local(port);}
00527
00528 #ifdef CCXX_IPV6
00529 IPV6Host getIPV6Local(tpport_t *port = NULL) const;
00530 #endif
00531
00559 IPV4Host getIPV4NAT(tpport_t *port = NULL) const;
00560
00561 inline IPV4Host getNAT(tpport_t *port) const
00562 {return getIPV4NAT(port);}
00563
00564 #ifdef CCXX_IPV6
00565 IPV6Host getIPV6NAT(tpport_t *port = NULL) const;
00566 #endif
00567
00578 void setCompletion(bool immediate);
00579
00585 Error setLinger(bool linger);
00586
00594 Error setKeepAlive(bool enable);
00595
00604 Error setTypeOfService(Tos service);
00605
00614 bool isConnected(void) const;
00615
00623 bool isActive(void) const;
00624
00629 bool operator!() const;
00630
00637 inline bool isBroadcast(void) const
00638 {return flags.broadcast;};
00639
00645 inline bool isRouted(void) const
00646 {return flags.route;};
00647
00654 inline Error getErrorNumber(void) const {return errid;}
00655
00662 inline const char *getErrorString(void) const {return errstr;}
00663
00664 inline long getSystemError(void) const {return syserr;}
00665
00666 const char *getSystemErrorString(void) const;
00667
00677 virtual bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
00678 };
00679
00712 class __EXPORT UDPSocket : public Socket
00713 {
00714 private:
00715 inline Error setKeepAlive(bool enable)
00716 {return Socket::setKeepAlive(enable);};
00717
00718 protected:
00719 #ifdef CCXX_IPV6
00720 union
00721 {
00722 struct sockaddr_in6 ipv6;
00723 struct sockaddr_in ipv4;
00724 } peer;
00725 #else
00726 union
00727 {
00728 struct sockaddr_in ipv4;
00729 } peer;
00730 #endif
00731
00732 Family family;
00733
00734 public:
00738 UDPSocket(Family family = IPV4);
00739
00743 UDPSocket(const char *name, Family family = IPV4);
00744
00754 UDPSocket(const IPV4Address &bind, tpport_t port);
00755 #ifdef CCXX_IPV6
00756 UDPSocket(const IPV6Address &bind, tpport_t port);
00757 #endif
00758
00762 virtual ~UDPSocket();
00763
00767 inline Error setLoopback(bool enable)
00768 {return Socket::setLoopbackByFamily(enable, family);}
00769
00773 inline Error setMulticast(bool enable)
00774 {return Socket::setMulticastByFamily(enable, family);}
00775
00779 inline Error setTimeToLive(char ttl)
00780 {return Socket::setTimeToLiveByFamily(ttl, family);}
00781
00789 void setPeer(const IPV4Host &host, tpport_t port);
00790 void connect(const IPV4Host &host, tpport_t port);
00791 #ifdef CCXX_IPV6
00792 void setPeer(const IPV6Host &host, tpport_t port);
00793 void connect(const IPV6Host &host, tpport_t port);
00794 #endif
00795
00803 Socket::Error getInterfaceIndex(const char *ethX,int& InterfaceIndex);
00804
00813 Socket::Error join(const IPV4Multicast &ia,int InterfaceIndex);
00814
00815
00823 ssize_t send(const void *buf, size_t len);
00824
00833 ssize_t receive(void *buf, size_t len, bool reply = false);
00834
00843 IPV4Host getIPV4Peer(tpport_t *port = NULL) const;
00844 inline IPV4Host getPeer(tpport_t *port = NULL) const
00845 {return getIPV4Peer(port);}
00846
00847 #ifdef CCXX_IPV6
00848 IPV6Host getIPV6Peer(tpport_t *port = NULL) const;
00849 #endif
00850
00858 inline ssize_t peek(void *buf, size_t len)
00859 {return _IORET64 ::recv(so, (char *)buf, _IOLEN64 len, MSG_PEEK);};
00860
00864 void setPeer(const char *service);
00865 void connect(const char *service);
00866
00871 Error disconnect(void);
00872 };
00873
00874
00883 class __EXPORT UDPBroadcast : public UDPSocket
00884 {
00885 private:
00886 void setPeer(const IPV4Host &ia, tpport_t port);
00887
00888 Error setBroadcast(bool enable)
00889 {return Socket::setBroadcast(enable);};
00890
00891 public:
00898 UDPBroadcast(const IPV4Address &ia, tpport_t port);
00899
00906 void setPeer(const IPV4Broadcast &subnet, tpport_t port);
00907 };
00908
00917 class __EXPORT UDPTransmit : protected UDPSocket
00918 {
00919 private:
00927 Error cConnect(const IPV4Address &ia, tpport_t port);
00928
00929 protected:
00933 UDPTransmit(Family family = IPV4);
00934
00946 UDPTransmit(const IPV4Address &bind, tpport_t port = 5005);
00947 #ifdef CCXX_IPV6
00948 UDPTransmit(const IPV6Address &bind, tpport_t port = 5005);
00949 #endif
00950
00960 Error connect(const IPV4Host &host, tpport_t port);
00961 #ifdef CCXX_IPV6
00962 Error connect(const IPV6Address &host, tpport_t port);
00963 #endif
00964
00974 Error connect(const IPV4Broadcast &subnet, tpport_t port);
00975
00983 Error connect(const IPV4Multicast &mgroup, tpport_t port);
00984 #ifdef CCXX_IPV6
00985 Error connect(const IPV6Multicast &mgroup, tpport_t port);
00986 #endif
00987
00995 inline ssize_t send(const void *buf, size_t len)
00996 {return _IORET64 ::send(so, (const char *)buf, _IOLEN64 len, 0);}
00997
01001 inline void endTransmitter(void)
01002 {Socket::endSocket();}
01003
01004
01005
01006
01007
01008
01009 inline SOCKET getTransmitter(void)
01010 {return so;};
01011
01012 inline Error setMulticast(bool enable)
01013 {return Socket::setMulticastByFamily(enable, family);}
01014
01015 inline Error setTimeToLive(unsigned char ttl)
01016 {return Socket::setTimeToLiveByFamily(ttl, family);};
01017
01018 public:
01028 inline ssize_t transmit(const char *buffer, size_t len)
01029 {return _IORET64 ::send(so, buffer, _IOLEN64 len, MSG_DONTWAIT);}
01030
01037 inline bool isOutputReady(unsigned long timeout = 0l)
01038 {return Socket::isPending(Socket::pendingOutput, timeout);};
01039
01040
01041 inline Error setRouting(bool enable)
01042 {return Socket::setRouting(enable);};
01043
01044 inline Error setTypeOfService(Tos tos)
01045 {return Socket::setTypeOfService(tos);};
01046
01047 inline Error setBroadcast(bool enable)
01048 {return Socket::setBroadcast(enable);};
01049 };
01050
01059 class __EXPORT UDPReceive : protected UDPSocket
01060 {
01061 protected:
01072 UDPReceive(const IPV4Address &bind, tpport_t port);
01073 #ifdef CCXX_IPV6
01074 UDPReceive(const IPV6Address &bind, tpport_t port);
01075 #endif
01076
01086 Error connect(const IPV4Host &host, tpport_t port);
01087 #ifdef CCXX_IPV6
01088 Error connect(const IPV6Host &host, tpport_t port);
01089 #endif
01090
01097 bool isPendingReceive(timeout_t timeout)
01098 {return Socket::isPending(Socket::pendingInput, timeout);};
01099
01103 inline void endReceiver(void)
01104 {Socket::endSocket();}
01105
01106 inline SOCKET getReceiver(void) const
01107 {return so;};
01108
01109 inline Error setRouting(bool enable)
01110 {return Socket::setRouting(enable);}
01111
01112 inline Error setMulticast(bool enable)
01113 {return Socket::setMulticastByFamily(enable, family);}
01114
01115 inline Error join(const IPV4Multicast &ia)
01116 {return Socket::join(ia);}
01117
01118 #ifdef CCXX_IPV6
01119 inline Error join(const IPV6Multicast &ia)
01120 {return Socket::join(ia);}
01121 #endif
01122
01123 inline Error drop(const IPV4Multicast &ia)
01124 {return Socket::drop(ia);}
01125
01126 #ifdef CCXX_IPV6
01127 inline Error drop(const IPV6Multicast &ia)
01128 {return Socket::drop(ia);}
01129 #endif
01130
01131 public:
01139 inline ssize_t receive(void *buf, size_t len)
01140 {return _IORET64 ::recv(so, (char *)buf, _IOLEN64 len, 0);};
01141
01148 inline bool isInputReady(timeout_t timeout = TIMEOUT_INF)
01149 {return Socket::isPending(Socket::pendingInput, timeout);};
01150 };
01151
01162 class __EXPORT UDPDuplex : public UDPTransmit, public UDPReceive
01163 {
01164 public:
01172 UDPDuplex(const IPV4Address &bind, tpport_t port);
01173 #ifdef CCXX_IPV6
01174 UDPDuplex(const IPV6Address &bind, tpport_t port);
01175 #endif
01176
01186 Error connect(const IPV4Host &host, tpport_t port);
01187 #ifdef CCXX_IPV6
01188 Error connect(const IPV6Host &host, tpport_t port);
01189 #endif
01190
01197 Error disconnect(void);
01198 };
01199
01200
01225 class __EXPORT TCPSocket : protected Socket
01226 {
01227 protected:
01228 int segsize;
01229 void setSegmentSize(unsigned mss);
01230
01231 public:
01243 virtual bool onAccept(const IPV4Host &ia, tpport_t port);
01244
01248 inline SOCKET getSocket(void)
01249 {return so;};
01250
01254 inline int getSegmentSize(void)
01255 {return segsize;};
01256
01269 TCPSocket(const IPV4Address &bind, tpport_t port, unsigned backlog = 5, unsigned mss = 536);
01270
01281 TCPSocket(const char *name, unsigned backlog = 5, unsigned mss = 536);
01282
01291 inline IPV4Host getRequest(tpport_t *port = NULL) const
01292 {return Socket::getIPV4Sender(port);}
01293
01297 void reject(void);
01298
01302 inline IPV4Host getLocal(tpport_t *port = NULL) const
01303 {return Socket::getIPV4Local(port);}
01304
01310 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF)
01311 {return Socket::isPending(Socket::pendingInput, timeout);}
01312
01316 virtual ~TCPSocket();
01317 };
01318
01319 #ifdef CCXX_IPV6
01320
01344 class __EXPORT TCPV6Socket : protected Socket
01345 {
01346 private:
01347 int segsize;
01348 void setSegmentSize(unsigned mss);
01349
01350 public:
01362 virtual bool onAccept(const IPV6Host &ia, tpport_t port);
01363
01367 inline SOCKET getSocket(void)
01368 {return so;};
01369
01370 inline int getSegmentSize(void)
01371 {return segsize;};
01372
01385 TCPV6Socket(const IPV6Address &bind, tpport_t port, unsigned backlog = 5, unsigned mss = 536);
01386
01397 TCPV6Socket(const char *name, unsigned backlog = 5, unsigned mss = 536);
01398
01407 inline IPV6Host getRequest(tpport_t *port = NULL) const
01408 {return Socket::getIPV6Sender(port);}
01409
01413 void reject(void);
01414
01418 inline IPV6Host getLocal(tpport_t *port = NULL) const
01419 {return Socket::getIPV6Local(port);}
01420
01426 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF)
01427 {return Socket::isPending(Socket::pendingInput, timeout);}
01428
01432 virtual ~TCPV6Socket();
01433 };
01434
01435 #endif
01436
01437
01438
01439
01440
01441
01442
01443
01444 #ifdef _MSC_VER
01445 #pragma warning(disable:4275) // disable C4275 warning
01446 #endif
01447
01461 class __EXPORT TCPStream : protected std::streambuf, public Socket, public std::iostream
01462 {
01463 private:
01464 int doallocate();
01465
01466 void segmentBuffering(unsigned mss);
01467
01468 friend TCPStream& crlf(TCPStream&);
01469 friend TCPStream& lfcr(TCPStream&);
01470
01471 protected:
01472 timeout_t timeout;
01473 size_t bufsize;
01474 Family family;
01475 char *gbuf, *pbuf;
01476
01477 public:
01482 TCPStream(Family family = IPV4, bool throwflag = true, timeout_t to = 0);
01483
01487 void disconnect(void);
01488
01492 int getSegmentSize(void);
01493
01494 protected:
01501 void allocate(size_t size);
01502
01507 void endStream(void);
01508
01515 int underflow();
01516
01525 int uflow();
01526
01534 int overflow(int ch);
01535
01544 void connect(const IPV4Host &host, tpport_t port, unsigned mss = 536);
01545 #ifdef CCXX_IPV6
01546 void connect(const IPV6Host &host, tpport_t port, unsigned mss = 536);
01547 #endif
01548
01556 void connect(const char *name, unsigned mss = 536);
01557
01565 std::iostream *tcp(void)
01566 {return ((std::iostream *)this);};
01567
01568 public:
01578 TCPStream(TCPSocket &server, bool throwflag = true, timeout_t timeout = 0);
01579 #ifdef CCXX_IPV6
01580 TCPStream(TCPV6Socket &server, bool throwflag = true, timeout_t timeout = 0);
01581 #endif
01582
01588 void connect(TCPSocket &server);
01589 #ifdef CCXX_IPV6
01590 void connect(TCPV6Socket &server);
01591 #endif
01592
01603 TCPStream(const IPV4Host &host, tpport_t port, unsigned mss = 536, bool throwflag = true, timeout_t timeout = 0);
01604 #ifdef CCXX_IPV6
01605 TCPStream(const IPV6Host &host, tpport_t port, unsigned mss = 536, bool throwflag = true, timeout_t timeout = 0);
01606 #endif
01607
01617 TCPStream(const char *name, Family family = IPV4, unsigned mss = 536, bool throwflag = false, timeout_t timer = 0);
01618
01624 inline void setTimeout(timeout_t timer)
01625 {timeout = timer;};
01626
01633 TCPStream(const TCPStream &source);
01634
01639 virtual ~TCPStream();
01640
01647 int sync(void);
01648
01649 #ifdef HAVE_SNPRINTF
01650
01656 size_t printf(const char *format, ...);
01657 #endif
01658
01666 bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
01667
01675 inline ssize_t peek(void *buf, size_t len)
01676 {return _IORET64 ::recv(so, (char *)buf, _IOLEN64 len, MSG_PEEK);};
01677
01683 inline size_t getBufferSize(void) const
01684 {return bufsize;};
01685 };
01686
01697 class __EXPORT TCPSession : public Thread, public TCPStream
01698 {
01699 private:
01700 TCPSession(const TCPSession &rhs);
01701 protected:
01714 int waitConnection(timeout_t timeout = TIMEOUT_INF);
01715
01722 void initial(void);
01723
01724 public:
01735 TCPSession(const IPV4Host &host,
01736 tpport_t port, size_t size = 536, int pri = 0, size_t stack = 0);
01737 #ifdef CCXX_IPV6
01738 TCPSession(const IPV6Host &host,
01739 tpport_t port, size_t size = 536, int pri = 0, size_t stack = 0);
01740 #endif
01741
01751 TCPSession(TCPSocket &server, int pri = 0, size_t stack = 0);
01752 #ifdef CCXX_IPV6
01753 TCPSession(TCPV6Socket &server, int pri = 0, size_t stack = 0);
01754 #endif
01755
01759 virtual ~TCPSession();
01760 };
01761
01762 #if defined(WIN32)
01763
01773 class init_WSA
01774 {
01775 public:
01776 init_WSA();
01777 ~init_WSA();
01778 };
01779
01780 #endif // WIN32
01781
01782 class __EXPORT SimpleTCPStream;
01783
01795 class __EXPORT SimpleTCPStream : public Socket
01796 {
01797 private:
01798
01799 IPV4Host getSender(tpport_t *port) const;
01800
01801 protected:
01806 SimpleTCPStream();
01807
01812 void endStream(void);
01813
01822 void Connect(const IPV4Host &host, tpport_t port, size_t size);
01823
01824
01825 public:
01834 SimpleTCPStream(TCPSocket &server, size_t size = 512);
01835
01844 SimpleTCPStream(const IPV4Host &host, tpport_t port, size_t size = 512);
01845
01851 SimpleTCPStream(const SimpleTCPStream &source);
01852
01857 virtual ~SimpleTCPStream();
01858
01870 bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
01871
01872 void flush() {}
01873
01885 ssize_t read(char *bytes, size_t length, timeout_t timeout = 0);
01886
01898 ssize_t write(const char *bytes, size_t length, timeout_t timeout = 0);
01899
01913 ssize_t peek(char *bytes, size_t length, timeout_t timeout = 0);
01914
01915 };
01916
01917 #ifdef COMMON_STD_EXCEPTION
01918 class __EXPORT SockException : public IOException
01919 {
01920 private:
01921 Socket::Error _socketError;
01922
01923 public:
01924 SockException(const String &str, Socket::Error socketError, long systemError = 0) :
01925 IOException(str, systemError), _socketError(socketError) {};
01926
01927 inline Socket::Error getSocketError() const
01928 { return _socketError; }
01929 };
01930 #endif
01931
01932 #ifdef CCXX_NAMESPACES
01933 }
01934 #endif
01935
01936 #endif
01937