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 {endSocket();};
00759
00763 Socket &operator=(const Socket &from);
00764
00774 InetHostAddress getSender(tpport_t *port = NULL) const;
00775
00785 InetHostAddress getPeer(tpport_t *port = NULL) const;
00786
00794 InetHostAddress getLocal(tpport_t *port = NULL) const;
00795
00806 void setCompletion(bool immediate);
00807
00813 sockerror_t setLinger(bool linger);
00814
00822 sockerror_t setKeepAlive(bool enable);
00823
00832 sockerror_t setTypeOfService(socktos_t service);
00833
00842 bool isConnected(void) const;
00843
00851 bool isActive(void) const;
00852
00857 bool operator!() const;
00858
00865 inline bool isBroadcast(void) const
00866 {return flags.broadcast;};
00867
00873 inline bool isRouted(void) const
00874 {return flags.route;};
00875
00882 inline sockerror_t getErrorNumber(void) const {return errid;}
00883
00890 inline const char *getErrorString(void) const {return errstr;}
00891
00901 virtual bool isPending(sockpend_t pend, timeout_t timeout = TIMEOUT_INF);
00902 };
00903
00936 class UDPSocket : public Socket
00937 {
00938 private:
00939 inline sockerror_t setKeepAlive(bool enable)
00940 {return Socket::setKeepAlive(enable);};
00941
00942 protected:
00943 struct sockaddr_in peer;
00944
00945 public:
00949 UDPSocket(void);
00950
00960 UDPSocket(const InetAddress &bind, tpport_t port);
00961
00965 virtual ~UDPSocket()
00966 {endSocket();};
00967
00975 void setPeer(const InetHostAddress &host, tpport_t port);
00976
00984 inline int Send(void *buf, size_t len)
00985 {return ::sendto(so, (const char *)buf, len, 0, (struct sockaddr *)&peer, (socklen_t)sizeof(peer));};
00986
00994 inline int Recv(void *buf, size_t len)
00995 {return ::recv(so, (char *)buf, len, 0);};
00996
01005 InetHostAddress getPeer(tpport_t *port = NULL) const;
01006
01014 inline int Peek(void *buf, size_t len)
01015 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
01016 };
01017
01018
01027 class UDPBroadcast : public UDPSocket
01028 {
01029 private:
01030 void setPeer(const InetHostAddress &ia, tpport_t port) {};
01031
01032 sockerror_t setBroadcast(bool enable)
01033 {return Socket::setBroadcast(enable);};
01034
01035 public:
01042 UDPBroadcast(const InetAddress &ia, tpport_t port);
01043
01050 void setPeer(const BroadcastAddress &subnet, tpport_t port);
01051 };
01052
01061 class UDPTransmit : private UDPSocket
01062 {
01063 protected:
01067 UDPTransmit();
01068
01081 UDPTransmit(const InetAddress &bind, tpport_t port = 5005);
01082
01091 sockerror_t Connect(const InetHostAddress &host, tpport_t port);
01092
01101 sockerror_t Connect(const BroadcastAddress &subnet, tpport_t port);
01102
01107 sockerror_t Disconnect(void);
01108
01116 inline int Send(void *buf, int len)
01117 {return ::send(so, (char *)buf, len, 0);}
01118
01122 inline void endTransmitter(void)
01123 {Socket::endSocket();}
01124
01125
01126
01127
01128
01129
01130 inline SOCKET getTransmitter(void)
01131 {return so;};
01132
01133 public:
01143 inline int Transmit(const char *buffer, size_t len)
01144 {return ::send(so, buffer, len, MSG_DONTWAIT);}
01145
01152 inline bool isOutputReady(unsigned long timeout = 0l)
01153 {return Socket::isPending(SOCKET_PENDING_OUTPUT, timeout);};
01154
01155
01156 inline sockerror_t setRouting(bool enable)
01157 {return Socket::setRouting(enable);};
01158
01159 inline sockerror_t setTypeOfService(socktos_t tos)
01160 {return Socket::setTypeOfService(tos);};
01161
01162 inline sockerror_t setBroadcast(bool enable)
01163 {return Socket::setBroadcast(enable);};
01164 };
01165
01174 class UDPReceive : private UDPSocket
01175 {
01176 protected:
01188 UDPReceive(const InetAddress &bind, tpport_t port);
01189
01198 sockerror_t Connect(const InetHostAddress &host, tpport_t port);
01199
01204 sockerror_t Disconnect(void);
01205
01212 bool isPendingReceive(timeout_t timeout)
01213 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);};
01214
01218 inline void endReceiver(void)
01219 {Socket::endSocket();}
01220
01221 inline SOCKET getReceiver(void)
01222 {return so;};
01223
01224 inline sockerror_t setRouting(bool enable)
01225 {return Socket::setRouting(enable);};
01226
01227 public:
01235 inline int Receive(void *buf, size_t len)
01236 {return ::recv(so, (char *)buf, len, 0);};
01237
01244 inline bool isInputReady(timeout_t timeout = TIMEOUT_INF)
01245 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);};
01246 };
01247
01258 class UDPDuplex : public UDPTransmit, public UDPReceive
01259 {
01260 public:
01269 UDPDuplex(const InetAddress &bind, tpport_t port);
01270
01280 sockerror_t Connect(const InetHostAddress &host, tpport_t port);
01281
01288 sockerror_t Disconnect(void);
01289 };
01290
01291
01316 class TCPSocket : private Socket
01317 {
01318 protected:
01330 virtual bool OnAccept(const InetHostAddress &ia, tpport_t port)
01331 {return true;};
01332
01333 friend class TCPStream;
01334 friend class SocketPort;
01335 friend class tcpstream;
01336
01337 public:
01349 TCPSocket(const InetAddress &bind, tpport_t port, int backlog = 5);
01350
01359 inline InetHostAddress getRequest(tpport_t *port = NULL) const
01360 {return Socket::getSender(port);};
01361
01365 void Reject(void);
01366
01370 inline InetHostAddress getLocal(tpport_t *port = NULL) const
01371 {return Socket::getLocal(port);};
01372
01376 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF)
01377 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);}
01378
01382 virtual ~TCPSocket()
01383 {endSocket();};
01384 };
01385
01386
01387
01388
01389
01390
01391
01392
01393 #ifdef _MSC_VER
01394 #pragma warning(disable:4275) // disable C4275 warning
01395 #endif
01396
01410 #if defined(STLPORT) || defined(__KCC)
01411 #define std::iostream std::iostream_withassign
01412 #endif
01413 #ifdef __KCC
01414 using std::iostream;
01415 #endif
01416 class TCPStream : public Socket, public std::streambuf, public std::iostream
01417 {
01418 private:
01419 inline sockerror_t setBroadcast(bool enable)
01420 {return Socket::setBroadcast(enable);};
01421
01422 inline InetHostAddress getSender(tpport_t *port) const
01423 {return InetHostAddress();};
01424
01425 int doallocate();
01426
01427 friend TCPStream& crlf(TCPStream&);
01428 friend TCPStream& lfcr(TCPStream&);
01429
01430 protected:
01431 timeout_t timeout;
01432 int bufsize;
01433 char *gbuf, *pbuf;
01434
01439 TCPStream(bool throwflag = true);
01440
01447 void Allocate(int size);
01448
01453 void endStream(void);
01454
01461 virtual int underflow(void);
01462
01471 int uflow(void);
01472
01480 int overflow(int ch);
01481
01490 void Connect(const InetHostAddress &host, tpport_t port, int size);
01491
01499 std::iostream *tcp(void)
01500 {return ((std::iostream *)this);};
01501
01502 public:
01512 TCPStream(TCPSocket &server, int size = 512, bool throwflag = true, timeout_t timeout = 0);
01513
01524 TCPStream(const InetHostAddress &host, tpport_t port, int size = 512, bool throwflag = true, timeout_t to = 0);
01525
01531 inline void setTimeout(timeout_t to)
01532 {timeout = to;};
01533
01540 TCPStream(const TCPStream &source);
01541
01546 virtual ~TCPStream()
01547 {endStream();};
01548
01555 int sync(void);
01556
01564 bool isPending(sockpend_t pend, timeout_t timeout = TIMEOUT_INF);
01565
01571 int getBufferSize(void) const
01572 {return bufsize;};
01573 };
01574
01583 class tcpstream : public TCPStream
01584 {
01585 public:
01589 tcpstream();
01590
01598 tcpstream(const char *addr, int buffer = 512);
01599
01607 tcpstream(TCPSocket &tcp, int buffer = 512);
01608
01616 void open(const char *addr, int buffer = 512);
01617
01624 void open(TCPSocket &tcp, int buffer = 512);
01625
01629 void close(void);
01630
01634 bool operator!() const;
01635 };
01636
01647 class TCPSession : public TCPStream, public Thread
01648 {
01649 protected:
01662 int WaitConnection(timeout_t timeout = TIMEOUT_INF);
01663
01670 CCXX_MEMBER(void) Initial(void);
01671
01677 CCXX_MEMBER(void) Final(void)
01678 {delete this;};
01679 public:
01690 TCPSession(const InetHostAddress &host,
01691 tpport_t port, int size = 512, int pri = 0, int stack = 0);
01692
01703 TCPSession(TCPSocket &server, int size = 512,
01704 int pri = 0, int stack = 0);
01705 };
01706
01707 extern CCXX_EXPORT(std::ostream&) operator<<(std::ostream &os, const InetAddress &ia);
01708
01709 inline struct in_addr getaddress(const InetAddress &ia)
01710 {return ia.getAddress();}
01711
01712 #if defined(WIN32)
01713
01724 class init_WSA
01725 {
01726 public:
01727 init_WSA();
01728 };
01729
01730 #else // !WIN32
01731
01732 class SocketService;
01733
01757 class SocketPort : public Socket, public TimerPort
01758 {
01759 private:
01760 SocketPort *next, *prev;
01761 SocketService *service;
01762 struct timeval porttimer;
01763 #ifdef __CCXX_USE_POLL
01764 struct pollfd * ufd;
01765 #endif
01766 bool detect_pending;
01767 bool detect_output;
01768 bool detect_disconnect;
01769
01770 friend class SocketService;
01771
01772 protected:
01781 SocketPort(SocketService *svc, TCPSocket &tcp);
01782
01791 SocketPort(SocketService *svc, const InetAddress &ia, tpport_t port);
01792
01798 void Attach( SocketService* svc );
01799
01800
01805 virtual ~SocketPort();
01806
01811 void setDetectPending( bool );
01812
01816 bool getDetectPending( void ) const
01817 { return detect_pending; }
01818
01823 void setDetectOutput( bool );
01824
01828 bool getDetectOutput( void ) const
01829 { return detect_output; }
01830
01835 virtual void Expired(void)
01836 {return;};
01837
01842 virtual void Pending(void)
01843 {return;};
01844
01849 virtual void Output(void)
01850 {return;};
01851
01856 virtual void Disconnect(void)
01857 {return;};
01858
01869 sockerror_t Connect(const InetAddress &ia, tpport_t port);
01870
01880 inline int Send(void *buf, int len)
01881 {return ::send(so, (char *)buf, len, 0);};
01882
01891 inline int Recv(void *buf, size_t len)
01892 {return ::recv(so, (char *)buf, len, 0);};
01893
01902 inline int Peek(void *buf, size_t len)
01903 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
01904
01905 public:
01913 void setTimer(timeout_t timeout = 0);
01914
01922 void incTimer(timeout_t timeout);
01923 };
01924
01937 class SocketService : public Thread, private Mutex
01938 {
01939 private:
01940 fd_set connect;
01941 int iosync[2];
01942 int hiwater;
01943 int count;
01944 SocketPort *first, *last;
01945
01951 void Attach(SocketPort *port);
01957 void Detach(SocketPort *port);
01958
01962 void Run(void);
01963
01964 friend class SocketPort;
01965
01966 protected:
01972 virtual void OnUpdate(unsigned char buf)
01973 {return;};
01974
01980 virtual void OnEvent(void)
01981 {return;};
01982
01990 virtual void OnCallback(SocketPort *port)
01991 {return;};
01992
01993 public:
02004 void Update(unsigned char flag = 0xff);
02005
02012 SocketService(int pri = 0);
02013
02018 virtual ~SocketService();
02019
02026 inline int getCount(void) const
02027 {return count;};
02028 };
02029
02030 #endif // !WIN32
02031
02032 #ifdef COMMON_STD_EXCEPTION
02033 class SockException : public IOException
02034 {
02035 public:
02036 SockException(std::string str) : IOException(str) {};
02037 };
02038 #endif
02039
02040 #ifdef __NAMESPACES__
02041 };
02042 #endif
02043
02044 #endif
02045