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 __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(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 protected:
01065 UDPTransmit();
01066
01079 UDPTransmit(const InetAddress &bind, tpport_t port = 5005);
01080
01089 sockerror_t Connect(const InetHostAddress &host, tpport_t port);
01090
01099 sockerror_t Connect(const BroadcastAddress &subnet, tpport_t port);
01100
01105 sockerror_t Disconnect(void);
01106
01114 inline int Send(void *buf, int len)
01115 {return ::send(so, (char *)buf, len, 0);}
01116
01120 inline void endTransmitter(void)
01121 {Socket::endSocket();}
01122
01123
01124
01125
01126
01127
01128 inline SOCKET getTransmitter(void)
01129 {return so;};
01130
01131 public:
01141 inline int Transmit(const char *buffer, size_t len)
01142 {return ::send(so, buffer, len, MSG_DONTWAIT);}
01143
01150 inline bool isOutputReady(unsigned long timeout = 0l)
01151 {return Socket::isPending(SOCKET_PENDING_OUTPUT, timeout);};
01152
01153
01154 inline sockerror_t setRouting(bool enable)
01155 {return Socket::setRouting(enable);};
01156
01157 inline sockerror_t setTypeOfService(socktos_t tos)
01158 {return Socket::setTypeOfService(tos);};
01159
01160 inline sockerror_t setBroadcast(bool enable)
01161 {return Socket::setBroadcast(enable);};
01162 };
01163
01172 class UDPReceive : private UDPSocket
01173 {
01174 protected:
01186 UDPReceive(const InetAddress &bind, tpport_t port);
01187
01196 sockerror_t Connect(const InetHostAddress &host, tpport_t port);
01197
01202 sockerror_t Disconnect(void);
01203
01210 bool isPendingReceive(timeout_t timeout)
01211 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);};
01212
01216 inline void endReceiver(void)
01217 {Socket::endSocket();}
01218
01219 inline SOCKET getReceiver(void)
01220 {return so;};
01221
01222 inline sockerror_t setRouting(bool enable)
01223 {return Socket::setRouting(enable);};
01224
01225 public:
01233 inline int Receive(void *buf, size_t len)
01234 {return ::recv(so, (char *)buf, len, 0);};
01235
01242 inline bool isInputReady(timeout_t timeout = TIMEOUT_INF)
01243 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);};
01244 };
01245
01256 class UDPDuplex : public UDPTransmit, public UDPReceive
01257 {
01258 public:
01267 UDPDuplex(const InetAddress &bind, tpport_t port);
01268
01278 sockerror_t Connect(const InetHostAddress &host, tpport_t port);
01279
01286 sockerror_t Disconnect(void);
01287 };
01288
01289
01314 class TCPSocket : private Socket
01315 {
01316 protected:
01328 virtual bool OnAccept(const InetHostAddress &ia, tpport_t port)
01329 {return true;};
01330
01331 friend class TCPStream;
01332 friend class SocketPort;
01333 friend class tcpstream;
01334
01335 public:
01347 TCPSocket(const InetAddress &bind, tpport_t port, int backlog = 5);
01348
01357 inline InetHostAddress getRequest(tpport_t *port = NULL) const
01358 {return Socket::getSender(port);};
01359
01363 void Reject(void);
01364
01368 inline InetHostAddress getLocal(tpport_t *port = NULL) const
01369 {return Socket::getLocal(port);};
01370
01374 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF)
01375 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);}
01376
01380 virtual ~TCPSocket()
01381 {endSocket();};
01382 };
01383
01384
01385
01386
01387
01388
01389
01390
01391 #ifdef _MSC_VER
01392 #pragma warning(disable:4275) // disable C4275 warning
01393 #endif
01394
01408 #if defined(STLPORT) || defined(__KCC)
01409 #define std::iostream std::iostream_withassign
01410 #endif
01411 #ifdef __KCC
01412 using std::iostream;
01413 #endif
01414 class TCPStream : public Socket, public std::streambuf, public std::iostream
01415 {
01416 private:
01417 inline sockerror_t setBroadcast(bool enable)
01418 {return Socket::setBroadcast(enable);};
01419
01420 inline InetHostAddress getSender(tpport_t *port) const
01421 {return InetHostAddress();};
01422
01423 int doallocate();
01424
01425 friend TCPStream& crlf(TCPStream&);
01426 friend TCPStream& lfcr(TCPStream&);
01427
01428 protected:
01429 timeout_t timeout;
01430 int bufsize;
01431 char *gbuf, *pbuf;
01432
01437 TCPStream(bool throwflag = true);
01438
01445 void Allocate(int size);
01446
01451 void endStream(void);
01452
01459 virtual int underflow(void);
01460
01469 int uflow(void);
01470
01478 int overflow(int ch);
01479
01488 void Connect(const InetHostAddress &host, tpport_t port, int size);
01489
01497 std::iostream *tcp(void)
01498 {return ((std::iostream *)this);};
01499
01500 public:
01510 TCPStream(TCPSocket &server, int size = 512, bool throwflag = true, timeout_t timeout = 0);
01511
01522 TCPStream(const InetHostAddress &host, tpport_t port, int size = 512, bool throwflag = true, timeout_t to = 0);
01523
01529 inline void setTimeout(timeout_t to)
01530 {timeout = to;};
01531
01538 TCPStream(const TCPStream &source);
01539
01544 virtual ~TCPStream()
01545 {endStream();};
01546
01553 int sync(void);
01554
01562 bool isPending(sockpend_t pend, timeout_t timeout = TIMEOUT_INF);
01563
01569 int getBufferSize(void) const
01570 {return bufsize;};
01571 };
01572
01581 class tcpstream : public TCPStream
01582 {
01583 public:
01587 tcpstream();
01588
01596 tcpstream(const char *addr, int buffer = 512);
01597
01605 tcpstream(TCPSocket &tcp, int buffer = 512);
01606
01614 void open(const char *addr, int buffer = 512);
01615
01622 void open(TCPSocket &tcp, int buffer = 512);
01623
01627 void close(void);
01628
01632 bool operator!() const;
01633 };
01634
01645 class TCPSession : public TCPStream, public Thread
01646 {
01647 protected:
01660 int WaitConnection(timeout_t timeout = TIMEOUT_INF);
01661
01668 CCXX_MEMBER(void) Initial(void);
01669
01675 CCXX_MEMBER(void) Final(void)
01676 {delete this;};
01677 public:
01688 TCPSession(const InetHostAddress &host,
01689 tpport_t port, int size = 512, int pri = 0, int stack = 0);
01690
01701 TCPSession(TCPSocket &server, int size = 512,
01702 int pri = 0, int stack = 0);
01703 };
01704
01705 extern CCXX_EXPORT(std::ostream&) operator<<(std::ostream &os, const InetAddress &ia);
01706
01707 inline struct in_addr getaddress(const InetAddress &ia)
01708 {return ia.getAddress();}
01709
01710 #if defined(WIN32)
01711
01722 class init_WSA
01723 {
01724 public:
01725 init_WSA();
01726 ~init_WSA();
01727 };
01728
01729 #else // !WIN32
01730
01731 class SocketService;
01732
01756 class SocketPort : public Socket, public TimerPort
01757 {
01758 private:
01759 SocketPort *next, *prev;
01760 SocketService *service;
01761 struct timeval porttimer;
01762 #ifdef __CCXX_USE_POLL
01763 struct pollfd * ufd;
01764 #endif
01765 bool detect_pending;
01766 bool detect_output;
01767 bool detect_disconnect;
01768
01769 friend class SocketService;
01770
01771 protected:
01780 SocketPort(SocketService *svc, TCPSocket &tcp);
01781
01790 SocketPort(SocketService *svc, const InetAddress &ia, tpport_t port);
01791
01797 void Attach( SocketService* svc );
01798
01799
01804 virtual ~SocketPort();
01805
01810 void setDetectPending( bool );
01811
01815 bool getDetectPending( void ) const
01816 { return detect_pending; }
01817
01822 void setDetectOutput( bool );
01823
01827 bool getDetectOutput( void ) const
01828 { return detect_output; }
01829
01834 virtual void Expired(void)
01835 {return;};
01836
01841 virtual void Pending(void)
01842 {return;};
01843
01848 virtual void Output(void)
01849 {return;};
01850
01855 virtual void Disconnect(void)
01856 {return;};
01857
01868 sockerror_t Connect(const InetAddress &ia, tpport_t port);
01869
01879 inline int Send(void *buf, int len)
01880 {return ::send(so, (char *)buf, len, 0);};
01881
01890 inline int Recv(void *buf, size_t len)
01891 {return ::recv(so, (char *)buf, len, 0);};
01892
01901 inline int Peek(void *buf, size_t len)
01902 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
01903
01904 public:
01912 void setTimer(timeout_t timeout = 0);
01913
01921 void incTimer(timeout_t timeout);
01922 };
01923
01936 class SocketService : public Thread, private Mutex
01937 {
01938 private:
01939 fd_set connect;
01940 int iosync[2];
01941 int hiwater;
01942 int count;
01943 SocketPort *first, *last;
01944
01950 void Attach(SocketPort *port);
01956 void Detach(SocketPort *port);
01957
01961 void Run(void);
01962
01963 friend class SocketPort;
01964
01965 protected:
01971 virtual void OnUpdate(unsigned char buf)
01972 {return;};
01973
01979 virtual void OnEvent(void)
01980 {return;};
01981
01989 virtual void OnCallback(SocketPort *port)
01990 {return;};
01991
01992 public:
02003 void Update(unsigned char flag = 0xff);
02004
02011 SocketService(int pri = 0);
02012
02017 virtual ~SocketService();
02018
02025 inline int getCount(void) const
02026 {return count;};
02027 };
02028
02029 #endif // !WIN32
02030
02031 #ifdef COMMON_STD_EXCEPTION
02032 class SockException : public IOException
02033 {
02034 public:
02035 SockException(std::string str) : IOException(str) {};
02036 };
02037 #endif
02038
02039 #ifdef __NAMESPACES__
02040 };
02041 #endif
02042
02043 #endif
02044