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
00038
00039
00040
00041 #ifndef CCXX_SOCKET_H_
00042 #define CCXX_SOCKET_H_
00043
00044 #ifndef CCXX_CONFIG_H_
00045 #include <cc++/config.h>
00046 #endif
00047
00048 #ifndef CCXX_THREAD_H_
00049 #include <cc++/thread.h>
00050 #endif
00051
00052 #ifdef WIN32
00053 #include <winsock.h>
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 #include <iostream>
00062
00063 #ifndef MSG_DONTWAIT
00064 #define MSG_DONTWAIT 0
00065 #endif
00066
00067 #ifdef CCXX_NAMESPACES
00068 namespace ost {
00069 #endif
00070
00075 enum sockstate_t
00076 {
00077 SOCKET_INITIAL,
00078 SOCKET_AVAILABLE,
00079 SOCKET_BOUND,
00080 SOCKET_CONNECTED,
00081 SOCKET_CONNECTING,
00082 SOCKET_STREAM
00083 };
00084 typedef enum sockstate_t sockstate_t;
00085
00086 enum sockerror_t
00087 {
00088 SOCKET_SUCCESS = 0,
00089 SOCKET_CREATE_FAILED,
00090 SOCKET_COPY_FAILED,
00091 SOCKET_INPUT_ERROR,
00092 SOCKET_INPUT_INTERRUPT,
00093 SOCKET_RESOURCE_FAILURE,
00094 SOCKET_OUTPUT_ERROR,
00095 SOCKET_OUTPUT_INTERRUPT,
00096 SOCKET_NOT_CONNECTED,
00097 SOCKET_CONNECT_REFUSED,
00098 SOCKET_CONNECT_REJECTED,
00099 SOCKET_CONNECT_TIMEOUT,
00100 SOCKET_CONNECT_FAILED,
00101 SOCKET_CONNECT_INVALID,
00102 SOCKET_CONNECT_BUSY,
00103 SOCKET_CONNECT_NOROUTE,
00104 SOCKET_BINDING_FAILED,
00105 SOCKET_BROADCAST_DENIED,
00106 SOCKET_ROUTING_DENIED,
00107 SOCKET_KEEPALIVE_DENIED,
00108 SOCKET_SERVICE_DENIED,
00109 SOCKET_SERVICE_UNAVAILABLE,
00110 SOCKET_MULTICAST_DISABLED,
00111 SOCKET_TIMEOUT_ERROR,
00112 SOCKET_NODELAY_ERROR,
00113 SOCKET_EXTENDED_ERROR
00114 };
00115 typedef enum sockerror_t sockerror_t;
00116
00117 enum socktos_t
00118 {
00119 SOCKET_IPTOS_LOWDELAY,
00120 SOCKET_IPTOS_THROUGHPUT,
00121 SOCKET_IPTOS_RELIABILITY,
00122 SOCKET_IPTOS_MINCOST,
00123 SOCKET_IPTOS_INVALID
00124 };
00125 typedef enum socktos_t socktos_t;
00126
00127 enum sockpend_t
00128 {
00129 SOCKET_PENDING_INPUT,
00130 SOCKET_PENDING_OUTPUT,
00131 SOCKET_PENDING_ERROR
00132 };
00133 typedef enum sockpend_t sockpend_t;
00134
00138 typedef unsigned short tpport_t;
00139
00140 class CCXX_CLASS_EXPORT InetAddress;
00141 class CCXX_CLASS_EXPORT InetHostAddress;
00142 class CCXX_CLASS_EXPORT InetMaskAddress;
00143 class CCXX_CLASS_EXPORT BroadcastAddress;
00144 class CCXX_CLASS_EXPORT Socket;
00145 class CCXX_CLASS_EXPORT UDPSocket;
00146 class CCXX_CLASS_EXPORT UDPBroadcast;
00147 class CCXX_CLASS_EXPORT UDPTransmit;
00148 class CCXX_CLASS_EXPORT UDPReceive;
00149 class CCXX_CLASS_EXPORT UDPDuplex;
00150 class CCXX_CLASS_EXPORT TCPSocket;
00151 class CCXX_CLASS_EXPORT TCPStream;
00152 class CCXX_CLASS_EXPORT tcpstream;
00153 class CCXX_CLASS_EXPORT TCPSession;
00154
00163 class InetAddrValidator
00164 {
00165 public:
00169 InetAddrValidator() { };
00170
00175 inline virtual void
00176 operator()(const in_addr address) const = 0;
00177 };
00178
00187 class InetMcastAddrValidator: public InetAddrValidator
00188 {
00189 public:
00193 InetMcastAddrValidator(){};
00194
00199 inline void
00200 operator()(const in_addr address) const;
00201 private:
00202 #if __BYTE_ORDER == __BIG_ENDIAN
00203 enum {
00204 MCAST_VALID_MASK = 0xF0000000,
00205 MCAST_VALID_VALUE = 0xE0000000
00206 };
00207 #else
00208 enum {
00209 MCAST_VALID_MASK = 0x000000F0,
00210 MCAST_VALID_VALUE = 0x000000E0
00211 };
00212 #endif
00213 };
00214
00229 class InetAddress
00230 {
00231 private:
00232
00233
00234
00235
00236
00237 const InetAddrValidator *validator;
00238
00239 protected:
00240 struct in_addr * ipaddr;
00241 size_t addr_count;
00242 #if defined(WIN32)
00243 static MutexCounter counter;
00244 #else
00245 static Mutex mutex;
00246 #endif
00247
00254 bool setIPAddress(const char *host);
00255
00262 void setAddress(const char *host);
00263
00264 public:
00272 InetAddress(const InetAddrValidator *validator = NULL);
00273
00282 InetAddress(struct in_addr addr, const InetAddrValidator *validator = NULL);
00283
00294 InetAddress(const char *address, const InetAddrValidator *validator = NULL);
00295
00299 InetAddress(const InetAddress &rhs);
00300
00304 virtual ~InetAddress();
00305
00312 const char *getHostname(void) const;
00313
00321 bool isInetAddress(void) const;
00322
00330 struct in_addr getAddress(void) const;
00331
00343 struct in_addr getAddress(size_t i) const;
00344
00350 size_t getAddressCount() const { return addr_count; }
00351
00352 InetAddress &operator=(const char *str);
00353 InetAddress &operator=(struct in_addr addr);
00354 InetAddress &operator=(const InetAddress &rhs);
00355
00360 InetAddress &operator=(unsigned long addr);
00361
00362 inline bool operator!() const
00363 {return !isInetAddress();};
00364
00373 bool operator==(const InetAddress &a) const;
00374
00382 bool operator!=(const InetAddress &a) const;
00383 };
00384
00397 class InetMaskAddress : public InetAddress
00398 {
00399 public:
00406 InetMaskAddress(const char *mask);
00407
00418 friend InetHostAddress operator&(const InetHostAddress &addr,
00419 const InetMaskAddress &mask);
00420
00425 InetAddress &operator=(unsigned long addr)
00426 { return InetAddress::operator =(addr); }
00427 };
00428
00436 class InetHostAddress : public InetAddress
00437 {
00438 public:
00451 InetHostAddress(const char *host = NULL);
00452
00460 InetHostAddress(struct in_addr addr);
00461
00466 InetAddress &operator=(unsigned long addr)
00467 { return InetAddress::operator =(addr); }
00468
00473 InetHostAddress &operator&=(const InetMaskAddress &mask);
00474
00475 friend class InetMaskAddress;
00476 friend InetHostAddress operator&(const InetHostAddress &addr,
00477 const InetMaskAddress &mask);
00478 };
00479
00484 class BroadcastAddress : public InetAddress
00485 {
00486 public:
00494 BroadcastAddress(const char *net = "255.255.255.255");
00495 };
00496
00506 class InetMcastAddress: public InetAddress
00507 {
00508 public:
00513 InetMcastAddress();
00514
00521 InetMcastAddress(const struct in_addr address);
00522
00532 InetMcastAddress(const char *address);
00533
00534 private:
00542 static const InetMcastAddrValidator validator;
00543 };
00544
00562 class Socket
00563 {
00564 private:
00565
00566 mutable sockerror_t errid;
00567 mutable const char *errstr;
00568
00569 void setSocket(void);
00570
00571 protected:
00572 mutable struct
00573 {
00574 bool thrown: 1;
00575 bool broadcast: 1;
00576 bool route: 1;
00577 bool keepalive: 1;
00578 bool loopback: 1;
00579 bool multicast: 1;
00580 bool completion: 1;
00581 bool linger: 1;
00582 unsigned ttl: 8;
00583 } flags;
00584
00590 SOCKET so;
00591 sockstate_t state;
00592
00600 sockerror_t Error(sockerror_t error, char *errstr = NULL) const;
00601
00608 inline void Error(char *estr)
00609 {Error(SOCKET_EXTENDED_ERROR, estr);};
00610
00617 inline void setError(bool enable)
00618 {flags.thrown = !enable;};
00619
00625 void endSocket(void);
00626
00632 sockerror_t connectError(void);
00633
00642 sockerror_t setBroadcast(bool enable);
00643
00654 sockerror_t setMulticast(bool enable);
00655
00663 sockerror_t setLoopback(bool enable);
00664
00671 sockerror_t setTimeToLive(unsigned char ttl);
00672
00679 sockerror_t Join(const InetMcastAddress &ia);
00680
00687 sockerror_t Drop(const InetMcastAddress &ia);
00688
00696 sockerror_t setRouting(bool enable);
00697
00698
00705 sockerror_t setNoDelay(bool enable);
00706
00718 Socket(int domain, int type, int protocol = 0);
00719
00727 Socket(SOCKET fd);
00728
00736 Socket(const Socket &source);
00737
00747 ssize_t Readline(char *buf, size_t len, timeout_t timeout = 0);
00748
00749 public:
00757 virtual ~Socket();
00758
00762 Socket &operator=(const Socket &from);
00763
00773 InetHostAddress getSender(tpport_t *port = NULL) const;
00774
00784 InetHostAddress getPeer(tpport_t *port = NULL) const;
00785
00793 InetHostAddress getLocal(tpport_t *port = NULL) const;
00794
00805 void setCompletion(bool immediate);
00806
00812 sockerror_t setLinger(bool linger);
00813
00821 sockerror_t setKeepAlive(bool enable);
00822
00831 sockerror_t setTypeOfService(socktos_t service);
00832
00841 bool isConnected(void) const;
00842
00850 bool isActive(void) const;
00851
00856 bool operator!() const;
00857
00864 inline bool isBroadcast(void) const
00865 {return flags.broadcast;};
00866
00872 inline bool isRouted(void) const
00873 {return flags.route;};
00874
00881 inline sockerror_t getErrorNumber(void) const {return errid;}
00882
00889 inline const char *getErrorString(void) const {return errstr;}
00890
00900 virtual bool isPending(sockpend_t pend, timeout_t timeout = TIMEOUT_INF);
00901 };
00902
00935 class UDPSocket : public Socket
00936 {
00937 private:
00938 inline sockerror_t setKeepAlive(bool enable)
00939 {return Socket::setKeepAlive(enable);};
00940
00941 protected:
00942 struct sockaddr_in peer;
00943
00944 public:
00948 UDPSocket(void);
00949
00959 UDPSocket(const InetAddress &bind, tpport_t port);
00960
00964 virtual ~UDPSocket();
00965
00973 void setPeer(const InetHostAddress &host, tpport_t port);
00974
00982 inline int Send(const void *buf, size_t len)
00983 {return ::sendto(so, (const char*)buf, len, 0, (struct sockaddr *)&peer, (socklen_t)sizeof(peer));};
00984
00992 inline int Recv(void *buf, size_t len)
00993 {return ::recv(so, (char *)buf, len, 0);};
00994
01003 InetHostAddress getPeer(tpport_t *port = NULL) const;
01004
01012 inline int Peek(void *buf, size_t len)
01013 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
01014 };
01015
01016
01025 class UDPBroadcast : public UDPSocket
01026 {
01027 private:
01028 void setPeer(const InetHostAddress &ia, tpport_t port) {};
01029
01030 sockerror_t setBroadcast(bool enable)
01031 {return Socket::setBroadcast(enable);};
01032
01033 public:
01040 UDPBroadcast(const InetAddress &ia, tpport_t port);
01041
01048 void setPeer(const BroadcastAddress &subnet, tpport_t port);
01049 };
01050
01059 class UDPTransmit : private UDPSocket
01060 {
01061 private:
01069 sockerror_t CConnect(const InetAddress &ia, tpport_t port);
01070
01071 protected:
01075 UDPTransmit();
01076
01089 UDPTransmit(const InetAddress &bind, tpport_t port = 5005);
01090
01099 sockerror_t Connect(const InetHostAddress &host, tpport_t port);
01100
01109 sockerror_t Connect(const BroadcastAddress &subnet, tpport_t port);
01110
01118 sockerror_t Connect(const InetMcastAddress &group, tpport_t port);
01119
01124 sockerror_t Disconnect(void);
01125
01133 inline int Send(const void *buf, int len)
01134 {return ::send(so, (const char *)buf, len, 0);}
01135
01139 inline void endTransmitter(void)
01140 {Socket::endSocket();}
01141
01142
01143
01144
01145
01146
01147 inline SOCKET getTransmitter(void)
01148 {return so;};
01149
01150 inline sockerror_t setMulticast(bool enable)
01151 {return Socket::setMulticast(enable);};
01152
01153 inline sockerror_t setTimeToLive(unsigned char ttl)
01154 {return Socket::setTimeToLive(ttl);};
01155
01156 public:
01166 inline int Transmit(const char *buffer, size_t len)
01167 {return ::send(so, buffer, len, MSG_DONTWAIT);}
01168
01175 inline bool isOutputReady(unsigned long timeout = 0l)
01176 {return Socket::isPending(SOCKET_PENDING_OUTPUT, timeout);};
01177
01178
01179 inline sockerror_t setRouting(bool enable)
01180 {return Socket::setRouting(enable);};
01181
01182 inline sockerror_t setTypeOfService(socktos_t tos)
01183 {return Socket::setTypeOfService(tos);};
01184
01185 inline sockerror_t setBroadcast(bool enable)
01186 {return Socket::setBroadcast(enable);};
01187 };
01188
01197 class UDPReceive : private UDPSocket
01198 {
01199 protected:
01211 UDPReceive(const InetAddress &bind, tpport_t port);
01212
01221 sockerror_t Connect(const InetHostAddress &host, tpport_t port);
01222
01227 sockerror_t Disconnect(void);
01228
01235 bool isPendingReceive(timeout_t timeout)
01236 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);};
01237
01241 inline void endReceiver(void)
01242 {Socket::endSocket();}
01243
01244 inline SOCKET getReceiver(void)
01245 {return so;};
01246
01247 inline sockerror_t setRouting(bool enable)
01248 {return Socket::setRouting(enable);};
01249
01250 inline sockerror_t setMulticast(bool enable)
01251 {return Socket::setMulticast(enable);};
01252
01253 inline sockerror_t Join(const InetMcastAddress &ia)
01254 {return Socket::Join(ia);}
01255
01256 inline sockerror_t Drop(const InetMcastAddress &ia)
01257 {return Socket::Drop(ia);}
01258
01259 public:
01267 inline int Receive(void *buf, size_t len)
01268 {return ::recv(so, (char *)buf, len, 0);};
01269
01276 inline bool isInputReady(timeout_t timeout = TIMEOUT_INF)
01277 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);};
01278 };
01279
01290 class UDPDuplex : public UDPTransmit, public UDPReceive
01291 {
01292 public:
01301 UDPDuplex(const InetAddress &bind, tpport_t port);
01302
01312 sockerror_t Connect(const InetHostAddress &host, tpport_t port);
01313
01320 sockerror_t Disconnect(void);
01321 };
01322
01323
01348 class TCPSocket : private Socket
01349 {
01350 protected:
01362 virtual bool OnAccept(const InetHostAddress &ia, tpport_t port)
01363 {return true;};
01364
01365 friend class TCPStream;
01366 friend class SocketPort;
01367 friend class tcpstream;
01368
01369 public:
01381 TCPSocket(const InetAddress &bind, tpport_t port, int backlog = 5);
01382
01391 inline InetHostAddress getRequest(tpport_t *port = NULL) const
01392 {return Socket::getSender(port);};
01393
01397 void Reject(void);
01398
01402 inline InetHostAddress getLocal(tpport_t *port = NULL) const
01403 {return Socket::getLocal(port);};
01404
01408 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF)
01409 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);}
01410
01414 virtual ~TCPSocket()
01415 {endSocket();};
01416 };
01417
01418
01419
01420
01421
01422
01423
01424
01425 #ifdef _MSC_VER
01426 #pragma warning(disable:4275) // disable C4275 warning
01427 #endif
01428
01442 #if defined(STLPORT) || defined(__KCC)
01443 #define std::iostream std::iostream_withassign
01444 #endif
01445 #ifdef __KCC
01446 using std::iostream;
01447 #endif
01448 class TCPStream : public Socket, public std::streambuf, public std::iostream
01449 {
01450 private:
01451 inline sockerror_t setBroadcast(bool enable)
01452 {return Socket::setBroadcast(enable);};
01453
01454 inline InetHostAddress getSender(tpport_t *port) const
01455 {return InetHostAddress();};
01456
01457 int doallocate();
01458
01459 friend TCPStream& crlf(TCPStream&);
01460 friend TCPStream& lfcr(TCPStream&);
01461
01462 protected:
01463 timeout_t timeout;
01464 int bufsize;
01465 char *gbuf, *pbuf;
01466
01471 TCPStream(bool throwflag = true);
01472
01479 void Allocate(int size);
01480
01485 void endStream(void);
01486
01493 virtual int underflow(void);
01494
01503 int uflow(void);
01504
01512 int overflow(int ch);
01513
01522 void Connect(const InetHostAddress &host, tpport_t port, int size);
01523
01531 std::iostream *tcp(void)
01532 {return ((std::iostream *)this);};
01533
01534 public:
01544 TCPStream(TCPSocket &server, int size = 512, bool throwflag = true, timeout_t timeout = 0);
01545
01556 TCPStream(const InetHostAddress &host, tpport_t port, int size = 512, bool throwflag = true, timeout_t to = 0);
01557
01563 inline void setTimeout(timeout_t to)
01564 {timeout = to;};
01565
01572 TCPStream(const TCPStream &source);
01573
01578 virtual ~TCPStream()
01579 {endStream();};
01580
01587 int sync(void);
01588
01596 bool isPending(sockpend_t pend, timeout_t timeout = TIMEOUT_INF);
01597
01603 int getBufferSize(void) const
01604 {return bufsize;};
01605 };
01606
01615 class tcpstream : public TCPStream
01616 {
01617 public:
01621 tcpstream();
01622
01630 tcpstream(const char *addr, int buffer = 512);
01631
01639 tcpstream(TCPSocket &tcp, int buffer = 512);
01640
01648 void open(const char *addr, int buffer = 512);
01649
01656 void open(TCPSocket &tcp, int buffer = 512);
01657
01661 void close(void);
01662
01666 bool operator!() const;
01667 };
01668
01679 class TCPSession : public TCPStream, public Thread
01680 {
01681 protected:
01694 int WaitConnection(timeout_t timeout = TIMEOUT_INF);
01695
01702 CCXX_MEMBER(void) Initial(void);
01703
01709 CCXX_MEMBER(void) Final(void)
01710 {delete this;};
01711 public:
01722 TCPSession(const InetHostAddress &host,
01723 tpport_t port, int size = 512, int pri = 0, int stack = 0);
01724
01735 TCPSession(TCPSocket &server, int size = 512,
01736 int pri = 0, int stack = 0);
01737 };
01738
01739 extern CCXX_EXPORT(std::ostream&) operator<<(std::ostream &os, const InetAddress &ia);
01740
01741 inline struct in_addr getaddress(const InetAddress &ia)
01742 {return ia.getAddress();}
01743
01744 #if defined(WIN32)
01745
01756 class init_WSA
01757 {
01758 public:
01759 init_WSA();
01760 ~init_WSA();
01761 };
01762
01763 #else // !WIN32
01764
01765 class SocketService;
01766
01790 class SocketPort : public Socket, public TimerPort
01791 {
01792 private:
01793 SocketPort *next, *prev;
01794 SocketService *service;
01795 struct timeval porttimer;
01796 #ifdef CCXX_USE_POLL
01797 struct pollfd * ufd;
01798 #endif
01799 bool detect_pending;
01800 bool detect_output;
01801 bool detect_disconnect;
01802
01803 friend class SocketService;
01804
01805 protected:
01814 SocketPort(SocketService *svc, TCPSocket &tcp);
01815
01824 SocketPort(SocketService *svc, const InetAddress &ia, tpport_t port);
01825
01831 void Attach( SocketService* svc );
01832
01833
01838 virtual ~SocketPort();
01839
01844 void setDetectPending( bool );
01845
01849 bool getDetectPending( void ) const
01850 { return detect_pending; }
01851
01856 void setDetectOutput( bool );
01857
01861 bool getDetectOutput( void ) const
01862 { return detect_output; }
01863
01868 virtual void Expired(void)
01869 {return;};
01870
01875 virtual void Pending(void)
01876 {return;};
01877
01882 virtual void Output(void)
01883 {return;};
01884
01889 virtual void Disconnect(void)
01890 {return;};
01891
01902 sockerror_t Connect(const InetAddress &ia, tpport_t port);
01903
01913 inline int Send(const void *buf, int len)
01914 {return ::send(so, (const char *)buf, len, 0);};
01915
01924 inline int Recv(void *buf, size_t len)
01925 {return ::recv(so, (char *)buf, len, 0);};
01926
01935 inline int Peek(void *buf, size_t len)
01936 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
01937
01938 public:
01946 void setTimer(timeout_t timeout = 0);
01947
01955 void incTimer(timeout_t timeout);
01956 };
01957
01970 class SocketService : public Thread, private Mutex
01971 {
01972 private:
01973 fd_set connect;
01974 int iosync[2];
01975 int hiwater;
01976 int count;
01977 SocketPort *first, *last;
01978
01984 void Attach(SocketPort *port);
01990 void Detach(SocketPort *port);
01991
01995 void Run(void);
01996
01997 friend class SocketPort;
01998
01999 protected:
02005 virtual void OnUpdate(unsigned char buf)
02006 {return;};
02007
02013 virtual void OnEvent(void)
02014 {return;};
02015
02023 virtual void OnCallback(SocketPort *port)
02024 {return;};
02025
02026 public:
02037 void Update(unsigned char flag = 0xff);
02038
02045 SocketService(int pri = 0);
02046
02051 virtual ~SocketService();
02052
02059 inline int getCount(void) const
02060 {return count;};
02061 };
02062
02063 #endif // !WIN32
02064
02065 #ifdef COMMON_STD_EXCEPTION
02066 class SockException : public IOException
02067 {
02068 public:
02069 SockException(std::string str) : IOException(str) {};
02070 };
02071 #endif
02072
02073 #ifdef CCXX_NAMESPACES
02074 };
02075 #endif
02076
02077 #endif
02078