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 #ifndef MSG_NOSIGNAL
00074 #define MSG_NOSIGNAL 0
00075 #endif
00076
00077 #ifdef CCXX_NAMESPACES
00078 namespace ost {
00079 #endif
00080
00084 typedef unsigned short tpport_t;
00085
00103 class __EXPORT Socket
00104 {
00105 public:
00106 enum Family {
00107 #ifdef CCXX_IPV6
00108 IPV6 = AF_INET6,
00109 #endif
00110 IPV4 = AF_INET
00111 };
00112
00113 typedef enum Family Family;
00114
00115 enum Error {
00116 errSuccess = 0,
00117 errCreateFailed,
00118 errCopyFailed,
00119 errInput,
00120 errInputInterrupt,
00121 errResourceFailure,
00122 errOutput,
00123 errOutputInterrupt,
00124 errNotConnected,
00125 errConnectRefused,
00126 errConnectRejected,
00127 errConnectTimeout,
00128 errConnectFailed,
00129 errConnectInvalid,
00130 errConnectBusy,
00131 errConnectNoRoute,
00132 errBindingFailed,
00133 errBroadcastDenied,
00134 errRoutingDenied,
00135 errKeepaliveDenied,
00136 errServiceDenied,
00137 errServiceUnavailable,
00138 errMulticastDisabled,
00139 errTimeout,
00140 errNoDelay,
00141 errExtended,
00142 errLookupFail,
00143 errSearchErr,
00144 errInvalidValue
00145 };
00146
00147 typedef enum Error Error;
00148
00149 enum Tos {
00150 tosLowDelay = 0,
00151 tosThroughput,
00152 tosReliability,
00153 tosMinCost,
00154 tosInvalid
00155 };
00156 typedef enum Tos Tos;
00157
00158 enum Pending {
00159 pendingInput,
00160 pendingOutput,
00161 pendingError
00162 };
00163 typedef enum Pending Pending;
00164
00165 protected:
00166 enum State {
00167 INITIAL,
00168 AVAILABLE,
00169 BOUND,
00170 CONNECTED,
00171 CONNECTING,
00172 STREAM
00173 };
00174 typedef enum State State;
00175
00176 private:
00177
00178 mutable Error errid;
00179 mutable const char *errstr;
00180 mutable long syserr;
00181
00182 void setSocket(void);
00183 friend SOCKET dupSocket(SOCKET s,Socket::State state);
00184
00185 protected:
00186 static Mutex mutex;
00187
00188 mutable struct {
00189 bool thrown: 1;
00190 bool broadcast: 1;
00191 bool route: 1;
00192 bool keepalive: 1;
00193 bool loopback: 1;
00194 bool multicast: 1;
00195 bool completion: 1;
00196 bool linger: 1;
00197 unsigned ttl: 8;
00198 } flags;
00199
00205 SOCKET volatile so;
00206 State volatile state;
00207
00216 Error error(Error error, char *err = NULL, long systemError = 0) const;
00217
00224 inline void error(char *err) const
00225 {error(errExtended, err);};
00226
00233 inline void setError(bool enable)
00234 {flags.thrown = !enable;};
00235
00241 void endSocket(void);
00242
00248 Error connectError(void);
00249
00253 Error sendLimit(int limit = 2048);
00254
00258 Error receiveLimit(int limit = 1);
00259
00266 Error sendTimeout(timeout_t timer);
00267
00274 Error receiveTimeout(timeout_t timer);
00275
00283 Error sendBuffer(unsigned size);
00284
00292 Error receiveBuffer(unsigned size);
00293
00301 Error bufferSize(unsigned size);
00302
00311 Error setBroadcast(bool enable);
00312
00324 Error setMulticastByFamily(bool enable, Family family = IPV4);
00325
00334 Error setLoopbackByFamily(bool enable, Family family = IPV4);
00335
00343 Error setTimeToLiveByFamily(unsigned char ttl, Family fam = IPV4);
00344
00351 Error join(const IPV4Multicast &ia);
00352 #ifdef CCXX_IPV6
00353 Error join(const IPV6Multicast &ia);
00354 #endif
00355
00362 Error drop(const IPV4Multicast &ia);
00363 #ifdef CCXX_IPV6
00364 Error drop(const IPV6Multicast &ia);
00365 #endif
00366
00374 Error setRouting(bool enable);
00375
00376
00383 Error setNoDelay(bool enable);
00384
00396 Socket(int domain, int type, int protocol = 0);
00397
00405 Socket(SOCKET fd);
00406
00410 Socket();
00411
00419 Socket(const Socket &source);
00420
00430 ssize_t readLine(char *buf, size_t len, timeout_t timeout = 0);
00431
00443 virtual ssize_t readData(void * buf,size_t len,char separator=0,timeout_t t=0);
00444
00453 virtual ssize_t writeData(const void* buf,size_t len,timeout_t t=0);
00454
00455 public:
00463 virtual ~Socket();
00464
00471 static bool check(Family fam);
00472
00476 Socket &operator=(const Socket &from);
00477
00487 IPV4Host getIPV4Sender(tpport_t *port = NULL) const;
00488
00489 inline IPV4Host getSender(tpport_t *port = NULL) const
00490 {return getIPV4Sender(port);}
00491
00492 #ifdef CCXX_IPV6
00493 IPV6Host getIPV6Sender(tpport_t *port = NULL) const;
00494 #endif
00495
00505 IPV4Host getIPV4Peer(tpport_t *port = NULL) const;
00506
00507 inline IPV4Host getPeer(tpport_t *port = NULL) const
00508 {return getIPV4Peer(port);}
00509
00510 #ifdef CCXX_IPV6
00511 IPV6Host getIPV6Peer(tpport_t *port = NULL) const;
00512 #endif
00513
00521 IPV4Host getIPV4Local(tpport_t *port = NULL) const;
00522
00523 inline IPV4Host getLocal(tpport_t *port = NULL) const
00524 {return getIPV4Local(port);}
00525
00526 #ifdef CCXX_IPV6
00527 IPV6Host getIPV6Local(tpport_t *port = NULL) const;
00528 #endif
00529
00557 IPV4Host getIPV4NAT(tpport_t *port = NULL) const;
00558
00559 inline IPV4Host getNAT(tpport_t *port) const
00560 {return getIPV4NAT(port);}
00561
00562 #ifdef CCXX_IPV6
00563 IPV6Host getIPV6NAT(tpport_t *port = NULL) const;
00564 #endif
00565
00576 void setCompletion(bool immediate);
00577
00583 Error setLinger(bool linger);
00584
00592 Error setKeepAlive(bool enable);
00593
00602 Error setTypeOfService(Tos service);
00603
00612 bool isConnected(void) const;
00613
00621 bool isActive(void) const;
00622
00627 bool operator!() const;
00628
00635 inline bool isBroadcast(void) const
00636 {return flags.broadcast;};
00637
00643 inline bool isRouted(void) const
00644 {return flags.route;};
00645
00652 inline Error getErrorNumber(void) const {return errid;}
00653
00660 inline const char *getErrorString(void) const {return errstr;}
00661
00662 inline long getSystemError(void) const {return syserr;}
00663
00664 const char *getSystemErrorString(void) const;
00665
00675 virtual bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
00676 };
00677
00710 class __EXPORT UDPSocket : public Socket
00711 {
00712 private:
00713 inline Error setKeepAlive(bool enable)
00714 {return Socket::setKeepAlive(enable);};
00715
00716 protected:
00717 #ifdef CCXX_IPV6
00718 union {
00719 struct sockaddr_in6 ipv6;
00720 struct sockaddr_in ipv4;
00721 } peer;
00722 #else
00723 union {
00724 struct sockaddr_in ipv4;
00725 } peer;
00726 #endif
00727
00728 Family family;
00729
00730 public:
00734 UDPSocket(Family family = IPV4);
00735
00739 UDPSocket(const char *name, Family family = IPV4);
00740
00750 UDPSocket(const IPV4Address &bind, tpport_t port);
00751 #ifdef CCXX_IPV6
00752 UDPSocket(const IPV6Address &bind, tpport_t port);
00753 #endif
00754
00758 virtual ~UDPSocket();
00759
00763 inline Error setLoopback(bool enable)
00764 {return Socket::setLoopbackByFamily(enable, family);}
00765
00769 inline Error setMulticast(bool enable)
00770 {return Socket::setMulticastByFamily(enable, family);}
00771
00775 inline Error setTimeToLive(char ttl)
00776 {return Socket::setTimeToLiveByFamily(ttl, family);}
00777
00785 void setPeer(const IPV4Host &host, tpport_t port);
00786 void connect(const IPV4Host &host, tpport_t port);
00787 #ifdef CCXX_IPV6
00788 void setPeer(const IPV6Host &host, tpport_t port);
00789 void connect(const IPV6Host &host, tpport_t port);
00790 #endif
00791
00799 Socket::Error getInterfaceIndex(const char *ethX,int& InterfaceIndex);
00800
00809 Socket::Error join(const IPV4Multicast &ia,int InterfaceIndex);
00810
00811
00819 ssize_t send(const void *buf, size_t len);
00820
00829 ssize_t receive(void *buf, size_t len, bool reply = false);
00830
00839 IPV4Host getIPV4Peer(tpport_t *port = NULL) const;
00840 inline IPV4Host getPeer(tpport_t *port = NULL) const
00841 {return getIPV4Peer(port);}
00842
00843 #ifdef CCXX_IPV6
00844 IPV6Host getIPV6Peer(tpport_t *port = NULL) const;
00845 #endif
00846
00854 inline ssize_t peek(void *buf, size_t len)
00855 {return _IORET64 ::recv(so, (char *)buf, _IOLEN64 len, MSG_PEEK);};
00856
00860 void setPeer(const char *service);
00861 void connect(const char *service);
00862
00867 Error disconnect(void);
00868 };
00869
00870
00879 class __EXPORT UDPBroadcast : public UDPSocket
00880 {
00881 private:
00882 void setPeer(const IPV4Host &ia, tpport_t port);
00883
00884 Error setBroadcast(bool enable)
00885 {return Socket::setBroadcast(enable);};
00886
00887 public:
00894 UDPBroadcast(const IPV4Address &ia, tpport_t port);
00895
00902 void setPeer(const IPV4Broadcast &subnet, tpport_t port);
00903 };
00904
00913 class __EXPORT UDPTransmit : protected UDPSocket
00914 {
00915 private:
00923 Error cConnect(const IPV4Address &ia, tpport_t port);
00924
00925 protected:
00929 UDPTransmit(Family family = IPV4);
00930
00942 UDPTransmit(const IPV4Address &bind, tpport_t port = 5005);
00943 #ifdef CCXX_IPV6
00944 UDPTransmit(const IPV6Address &bind, tpport_t port = 5005);
00945 #endif
00946
00956 Error connect(const IPV4Host &host, tpport_t port);
00957 #ifdef CCXX_IPV6
00958 Error connect(const IPV6Address &host, tpport_t port);
00959 #endif
00960
00970 Error connect(const IPV4Broadcast &subnet, tpport_t port);
00971
00979 Error connect(const IPV4Multicast &mgroup, tpport_t port);
00980 #ifdef CCXX_IPV6
00981 Error connect(const IPV6Multicast &mgroup, tpport_t port);
00982 #endif
00983
00991 inline ssize_t send(const void *buf, size_t len)
00992 {return _IORET64 ::send(so, (const char *)buf, _IOLEN64 len, MSG_NOSIGNAL);}
00993
00997 inline void endTransmitter(void)
00998 {Socket::endSocket();}
00999
01000
01001
01002
01003
01004
01005 inline SOCKET getTransmitter(void)
01006 {return so;};
01007
01008 inline Error setMulticast(bool enable)
01009 {return Socket::setMulticastByFamily(enable, family);}
01010
01011 inline Error setTimeToLive(unsigned char ttl)
01012 {return Socket::setTimeToLiveByFamily(ttl, family);};
01013
01014 public:
01024 inline ssize_t transmit(const char *buffer, size_t len)
01025 {return _IORET64 ::send(so, buffer, _IOLEN64 len, MSG_DONTWAIT|MSG_NOSIGNAL);}
01026
01033 inline bool isOutputReady(unsigned long timeout = 0l)
01034 {return Socket::isPending(Socket::pendingOutput, timeout);};
01035
01036
01037 inline Error setRouting(bool enable)
01038 {return Socket::setRouting(enable);};
01039
01040 inline Error setTypeOfService(Tos tos)
01041 {return Socket::setTypeOfService(tos);};
01042
01043 inline Error setBroadcast(bool enable)
01044 {return Socket::setBroadcast(enable);};
01045 };
01046
01055 class __EXPORT UDPReceive : protected UDPSocket
01056 {
01057 protected:
01068 UDPReceive(const IPV4Address &bind, tpport_t port);
01069 #ifdef CCXX_IPV6
01070 UDPReceive(const IPV6Address &bind, tpport_t port);
01071 #endif
01072
01082 Error connect(const IPV4Host &host, tpport_t port);
01083 #ifdef CCXX_IPV6
01084 Error connect(const IPV6Host &host, tpport_t port);
01085 #endif
01086
01093 bool isPendingReceive(timeout_t timeout)
01094 {return Socket::isPending(Socket::pendingInput, timeout);};
01095
01099 inline void endReceiver(void)
01100 {Socket::endSocket();}
01101
01102 inline SOCKET getReceiver(void) const
01103 {return so;};
01104
01105 inline Error setRouting(bool enable)
01106 {return Socket::setRouting(enable);}
01107
01108 inline Error setMulticast(bool enable)
01109 {return Socket::setMulticastByFamily(enable, family);}
01110
01111 inline Error join(const IPV4Multicast &ia)
01112 {return Socket::join(ia);}
01113
01114 #ifdef CCXX_IPV6
01115 inline Error join(const IPV6Multicast &ia)
01116 {return Socket::join(ia);}
01117 #endif
01118
01119 inline Error drop(const IPV4Multicast &ia)
01120 {return Socket::drop(ia);}
01121
01122 #ifdef CCXX_IPV6
01123 inline Error drop(const IPV6Multicast &ia)
01124 {return Socket::drop(ia);}
01125 #endif
01126
01127 public:
01135 inline ssize_t receive(void *buf, size_t len)
01136 {return _IORET64 ::recv(so, (char *)buf, _IOLEN64 len, 0);};
01137
01144 inline bool isInputReady(timeout_t timeout = TIMEOUT_INF)
01145 {return Socket::isPending(Socket::pendingInput, timeout);};
01146 };
01147
01158 class __EXPORT UDPDuplex : public UDPTransmit, public UDPReceive
01159 {
01160 public:
01168 UDPDuplex(const IPV4Address &bind, tpport_t port);
01169 #ifdef CCXX_IPV6
01170 UDPDuplex(const IPV6Address &bind, tpport_t port);
01171 #endif
01172
01182 Error connect(const IPV4Host &host, tpport_t port);
01183 #ifdef CCXX_IPV6
01184 Error connect(const IPV6Host &host, tpport_t port);
01185 #endif
01186
01193 Error disconnect(void);
01194 };
01195
01196
01221 class __EXPORT TCPSocket : protected Socket
01222 {
01223 protected:
01224 int segsize;
01225 void setSegmentSize(unsigned mss);
01226
01227 public:
01239 virtual bool onAccept(const IPV4Host &ia, tpport_t port);
01240
01244 inline SOCKET getSocket(void)
01245 {return so;};
01246
01250 inline int getSegmentSize(void)
01251 {return segsize;};
01252
01265 TCPSocket(const IPV4Address &bind, tpport_t port, unsigned backlog = 5, unsigned mss = 536);
01266
01277 TCPSocket(const char *name, unsigned backlog = 5, unsigned mss = 536);
01278
01287 inline IPV4Host getRequest(tpport_t *port = NULL) const
01288 {return Socket::getIPV4Sender(port);}
01289
01293 void reject(void);
01294
01298 inline IPV4Host getLocal(tpport_t *port = NULL) const
01299 {return Socket::getIPV4Local(port);}
01300
01306 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF)
01307 {return Socket::isPending(Socket::pendingInput, timeout);}
01308
01312 virtual ~TCPSocket();
01313 };
01314
01315 #ifdef CCXX_IPV6
01316
01340 class __EXPORT TCPV6Socket : protected Socket
01341 {
01342 private:
01343 int segsize;
01344 void setSegmentSize(unsigned mss);
01345
01346 public:
01358 virtual bool onAccept(const IPV6Host &ia, tpport_t port);
01359
01363 inline SOCKET getSocket(void)
01364 {return so;};
01365
01366 inline int getSegmentSize(void)
01367 {return segsize;};
01368
01381 TCPV6Socket(const IPV6Address &bind, tpport_t port, unsigned backlog = 5, unsigned mss = 536);
01382
01393 TCPV6Socket(const char *name, unsigned backlog = 5, unsigned mss = 536);
01394
01403 inline IPV6Host getRequest(tpport_t *port = NULL) const
01404 {return Socket::getIPV6Sender(port);}
01405
01409 void reject(void);
01410
01414 inline IPV6Host getLocal(tpport_t *port = NULL) const
01415 {return Socket::getIPV6Local(port);}
01416
01422 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF)
01423 {return Socket::isPending(Socket::pendingInput, timeout);}
01424
01428 virtual ~TCPV6Socket();
01429 };
01430
01431 #endif
01432
01433
01434
01435
01436
01437
01438
01439
01440 #ifdef _MSC_VER
01441 #pragma warning(disable:4275) // disable C4275 warning
01442 #endif
01443
01457 class __EXPORT TCPStream : protected std::streambuf, public Socket, public std::iostream
01458 {
01459 private:
01460 int doallocate();
01461
01462 void segmentBuffering(unsigned mss);
01463
01464 friend TCPStream& crlf(TCPStream&);
01465 friend TCPStream& lfcr(TCPStream&);
01466
01467 protected:
01468 timeout_t timeout;
01469 size_t bufsize;
01470 Family family;
01471 char *gbuf, *pbuf;
01472
01473 public:
01478 TCPStream(Family family = IPV4, bool throwflag = true, timeout_t to = 0);
01479
01483 void disconnect(void);
01484
01488 int getSegmentSize(void);
01489
01490 protected:
01497 void allocate(size_t size);
01498
01503 void endStream(void);
01504
01511 int underflow();
01512
01521 int uflow();
01522
01530 int overflow(int ch);
01531
01540 void connect(const IPV4Host &host, tpport_t port, unsigned mss = 536);
01541 #ifdef CCXX_IPV6
01542 void connect(const IPV6Host &host, tpport_t port, unsigned mss = 536);
01543 #endif
01544
01552 void connect(const char *name, unsigned mss = 536);
01553
01561 std::iostream *tcp(void)
01562 {return ((std::iostream *)this);};
01563
01564 public:
01574 TCPStream(TCPSocket &server, bool throwflag = true, timeout_t timeout = 0);
01575 #ifdef CCXX_IPV6
01576 TCPStream(TCPV6Socket &server, bool throwflag = true, timeout_t timeout = 0);
01577 #endif
01578
01584 void connect(TCPSocket &server);
01585 #ifdef CCXX_IPV6
01586 void connect(TCPV6Socket &server);
01587 #endif
01588
01599 TCPStream(const IPV4Host &host, tpport_t port, unsigned mss = 536, bool throwflag = true, timeout_t timeout = 0);
01600 #ifdef CCXX_IPV6
01601 TCPStream(const IPV6Host &host, tpport_t port, unsigned mss = 536, bool throwflag = true, timeout_t timeout = 0);
01602 #endif
01603
01613 TCPStream(const char *name, Family family = IPV4, unsigned mss = 536, bool throwflag = false, timeout_t timer = 0);
01614
01620 inline void setTimeout(timeout_t timer)
01621 {timeout = timer;};
01622
01629 TCPStream(const TCPStream &source);
01630
01635 virtual ~TCPStream();
01636
01643 int sync(void);
01644
01645 #ifdef HAVE_SNPRINTF
01646
01652 size_t printf(const char *format, ...);
01653 #endif
01654
01662 bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
01663
01671 inline ssize_t peek(void *buf, size_t len)
01672 {return _IORET64 ::recv(so, (char *)buf, _IOLEN64 len, MSG_PEEK);};
01673
01679 inline size_t getBufferSize(void) const
01680 {return bufsize;};
01681 };
01682
01693 class __EXPORT TCPSession : public Thread, public TCPStream
01694 {
01695 private:
01696 TCPSession(const TCPSession &rhs);
01697 protected:
01710 int waitConnection(timeout_t timeout = TIMEOUT_INF);
01711
01718 void initial(void);
01719
01720 public:
01731 TCPSession(const IPV4Host &host,
01732 tpport_t port, size_t size = 536, int pri = 0, size_t stack = 0);
01733 #ifdef CCXX_IPV6
01734 TCPSession(const IPV6Host &host,
01735 tpport_t port, size_t size = 536, int pri = 0, size_t stack = 0);
01736 #endif
01737
01747 TCPSession(TCPSocket &server, int pri = 0, size_t stack = 0);
01748 #ifdef CCXX_IPV6
01749 TCPSession(TCPV6Socket &server, int pri = 0, size_t stack = 0);
01750 #endif
01751
01755 virtual ~TCPSession();
01756 };
01757
01758 #if defined(WIN32)
01759
01769 class init_WSA
01770 {
01771 public:
01772 init_WSA();
01773 ~init_WSA();
01774 };
01775
01776 #endif // WIN32
01777
01778 class __EXPORT SimpleTCPStream;
01779
01791 class __EXPORT SimpleTCPStream : public Socket
01792 {
01793 private:
01794
01795 IPV4Host getSender(tpport_t *port) const;
01796
01797 protected:
01802 SimpleTCPStream();
01803
01808 void endStream(void);
01809
01818 void Connect(const IPV4Host &host, tpport_t port, size_t size);
01819
01820
01821 public:
01830 SimpleTCPStream(TCPSocket &server, size_t size = 512);
01831
01840 SimpleTCPStream(const IPV4Host &host, tpport_t port, size_t size = 512);
01841
01847 SimpleTCPStream(const SimpleTCPStream &source);
01848
01853 virtual ~SimpleTCPStream();
01854
01866 bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
01867
01868 void flush() {}
01869
01881 ssize_t read(char *bytes, size_t length, timeout_t timeout = 0);
01882
01894 ssize_t write(const char *bytes, size_t length, timeout_t timeout = 0);
01895
01909 ssize_t peek(char *bytes, size_t length, timeout_t timeout = 0);
01910
01911 };
01912
01913 #ifdef COMMON_STD_EXCEPTION
01914 class __EXPORT SockException : public IOException
01915 {
01916 private:
01917 Socket::Error _socketError;
01918
01919 public:
01920 SockException(const String &str, Socket::Error socketError, long systemError = 0) :
01921 IOException(str, systemError), _socketError(socketError) {};
01922
01923 inline Socket::Error getSocketError() const
01924 { return _socketError; }
01925 };
01926 #endif
01927
01928 #ifdef CCXX_NAMESPACES
01929 }
01930 #endif
01931
01932 #endif
01933