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
00046 #ifndef CCXX_SOCKET_H_
00047 #define CCXX_SOCKET_H_
00048
00049 #ifndef CCXX_CONFIG_H_
00050 #include <cc++/config.h>
00051 #endif
00052
00053 #ifndef CCXX_THREAD_H_
00054 #include <cc++/thread.h>
00055 #endif
00056
00057 #if defined(WIN32) && !defined(__CYGWIN32__)
00058 #define __WINSOCK__
00059 #include <winsock2.h>
00060 #include <io.h>
00061 #define TIMEOUT_INF ~((timeout_t) 0)
00062 typedef int socklen_t;
00063 #else
00064 #define INVALID_SOCKET -1
00065 typedef int SOCKET;
00066 #endif
00067
00068 #include <iostream>
00069
00070 #ifndef MSG_DONTWAIT
00071 #define MSG_DONTWAIT 0
00072 #endif
00073
00074 #ifdef CCXX_NAMESPACES
00075 namespace ost {
00076 #endif
00077
00078
00079
00083 typedef unsigned short tpport_t;
00084
00085 class CCXX_CLASS_EXPORT InetAddress;
00086 class CCXX_CLASS_EXPORT InetHostAddress;
00087 class CCXX_CLASS_EXPORT InetMaskAddress;
00088 class CCXX_CLASS_EXPORT BroadcastAddress;
00089 class CCXX_CLASS_EXPORT Socket;
00090 class CCXX_CLASS_EXPORT UDPSocket;
00091 class CCXX_CLASS_EXPORT UDPBroadcast;
00092 class CCXX_CLASS_EXPORT UDPTransmit;
00093 class CCXX_CLASS_EXPORT UDPReceive;
00094 class CCXX_CLASS_EXPORT UDPDuplex;
00095 class CCXX_CLASS_EXPORT TCPSocket;
00096 class CCXX_CLASS_EXPORT TCPStream;
00097 class CCXX_CLASS_EXPORT tcpstream;
00098 class CCXX_CLASS_EXPORT TCPSession;
00099 class CCXX_CLASS_EXPORT SocketPort;
00100 class CCXX_CLASS_EXPORT SocketService;
00101
00110 class InetAddrValidator
00111 {
00112 public:
00116 InetAddrValidator() { };
00117
00122 inline virtual void
00123 operator()(const in_addr address) const = 0;
00124 };
00125
00134 class InetMcastAddrValidator: public InetAddrValidator
00135 {
00136 public:
00140 InetMcastAddrValidator(){};
00141
00146 inline void
00147 operator()(const in_addr address) const;
00148 private:
00149 #if __BYTE_ORDER == __BIG_ENDIAN
00150 enum {
00151 MCAST_VALID_MASK = 0xF0000000,
00152 MCAST_VALID_VALUE = 0xE0000000
00153 };
00154 #else
00155 enum {
00156 MCAST_VALID_MASK = 0x000000F0,
00157 MCAST_VALID_VALUE = 0x000000E0
00158 };
00159 #endif
00160 };
00161
00176 class InetAddress
00177 {
00178 private:
00179
00180
00181
00182
00183
00184 const InetAddrValidator *validator;
00185
00186 protected:
00187 struct in_addr * ipaddr;
00188 size_t addr_count;
00189 mutable char* hostname;
00190 #if defined(WIN32)
00191 static MutexCounter counter;
00192 #else
00193 static Mutex mutex;
00194 #endif
00195
00202 bool setIPAddress(const char *host);
00203
00210 void setAddress(const char *host);
00211
00212 public:
00220 InetAddress(const InetAddrValidator *validator = NULL);
00221
00230 InetAddress(struct in_addr addr, const InetAddrValidator *validator = NULL);
00231
00242 InetAddress(const char *address, const InetAddrValidator *validator = NULL);
00243
00247 InetAddress(const InetAddress &rhs);
00248
00252 virtual ~InetAddress();
00253
00260 const char *getHostname(void) const;
00261
00269 bool isInetAddress(void) const;
00270
00278 struct in_addr getAddress(void) const;
00279
00291 struct in_addr getAddress(size_t i) const;
00292
00298 size_t getAddressCount() const { return addr_count; }
00299
00300 InetAddress &operator=(const char *str);
00301 InetAddress &operator=(struct in_addr addr);
00302 InetAddress &operator=(const InetAddress &rhs);
00303
00308 InetAddress &operator=(unsigned long addr);
00309
00310 inline InetAddress &operator=(unsigned int addr)
00311 {return *this = (unsigned long) addr; }
00312
00313 inline bool operator!() const
00314 {return !isInetAddress();};
00315
00324 bool operator==(const InetAddress &a) const;
00325
00333 bool operator!=(const InetAddress &a) const;
00334 };
00335
00348 class InetMaskAddress : public InetAddress
00349 {
00350 public:
00357 InetMaskAddress(const char *mask);
00358
00369 friend InetHostAddress operator&(const InetHostAddress &addr,
00370 const InetMaskAddress &mask);
00371
00376 InetAddress &operator=(unsigned long addr)
00377 { return InetAddress::operator =(addr); }
00378 };
00379
00387 class InetHostAddress : public InetAddress
00388 {
00389 public:
00402 InetHostAddress(const char *host = NULL);
00403
00411 InetHostAddress(struct in_addr addr);
00412
00417 InetAddress &operator=(unsigned long addr)
00418 { return InetAddress::operator =(addr); }
00419
00424 InetHostAddress &operator&=(const InetMaskAddress &mask);
00425
00426 friend class InetMaskAddress;
00427 friend InetHostAddress operator&(const InetHostAddress &addr,
00428 const InetMaskAddress &mask);
00429 };
00430
00435 class BroadcastAddress : public InetAddress
00436 {
00437 public:
00445 BroadcastAddress(const char *net = "255.255.255.255");
00446 };
00447
00457 class InetMcastAddress: public InetAddress
00458 {
00459 public:
00464 InetMcastAddress();
00465
00472 InetMcastAddress(const struct in_addr address);
00473
00483 InetMcastAddress(const char *address);
00484
00485 private:
00493 static const InetMcastAddrValidator validator;
00494 };
00495
00513 class Socket
00514 {
00515 public:
00516 enum Error
00517 {
00518 errSuccess = 0,
00519 errCreateFailed,
00520 errCopyFailed,
00521 errInput,
00522 errInputInterrupt,
00523 errResourceFailure,
00524 errOutput,
00525 errOutputInterrupt,
00526 errNotConnected,
00527 errConnectRefused,
00528 errConnectRejected,
00529 errConnectTimeout,
00530 errConnectFailed,
00531 errConnectInvalid,
00532 errConnectBusy,
00533 errConnectNoRoute,
00534 errBindingFailed,
00535 errBroadcastDenied,
00536 errRoutingDenied,
00537 errKeepaliveDenied,
00538 errServiceDenied,
00539 errServiceUnavailable,
00540 errMulticastDisabled,
00541 errTimeout,
00542 errNoDelay,
00543 errExtended
00544 };
00545
00546 typedef enum Error Error;
00547
00548 enum Tos
00549 {
00550 tosLowDelay = 0,
00551 tosThroughput,
00552 tosReliability,
00553 tosMinCost,
00554 tosInvalid
00555 };
00556 typedef enum Tos Tos;
00557
00558 enum Pending
00559 {
00560 pendingInput,
00561 pendingOutput,
00562 pendingError
00563 };
00564 typedef enum Pending Pending;
00565
00566 protected:
00567 enum State
00568 {
00569 INITIAL,
00570 AVAILABLE,
00571 BOUND,
00572 CONNECTED,
00573 CONNECTING,
00574 STREAM
00575 };
00576 typedef enum State State;
00577
00578 private:
00579
00580 mutable Error errid;
00581 mutable const char *errstr;
00582
00583 void setSocket(void);
00584 friend SOCKET dupSocket(SOCKET s,Socket::State state);
00585
00586 protected:
00587 mutable struct
00588 {
00589 bool thrown: 1;
00590 bool broadcast: 1;
00591 bool route: 1;
00592 bool keepalive: 1;
00593 bool loopback: 1;
00594 bool multicast: 1;
00595 bool completion: 1;
00596 bool linger: 1;
00597 unsigned ttl: 8;
00598 } flags;
00599
00605 SOCKET so;
00606 State state;
00607
00615 Error error(Error error, char *errstr = NULL) const;
00616
00623 inline void error(char *errstr) const
00624 {error(errExtended, errstr);};
00625
00632 inline void setError(bool enable)
00633 {flags.thrown = !enable;};
00634
00640 void endSocket(void);
00641
00647 Error connectError(void);
00648
00657 Error setBroadcast(bool enable);
00658
00669 Error setMulticast(bool enable);
00670
00678 Error setLoopback(bool enable);
00679
00686 Error setTimeToLive(unsigned char ttl);
00687
00694 Error join(const InetMcastAddress &ia);
00695
00702 Error drop(const InetMcastAddress &ia);
00703
00711 Error setRouting(bool enable);
00712
00713
00720 Error setNoDelay(bool enable);
00721
00733 Socket(int domain, int type, int protocol = 0);
00734
00742 Socket(SOCKET fd);
00743
00751 Socket(const Socket &source);
00752
00762 ssize_t readLine(char *buf, size_t len, timeout_t timeout = 0);
00763
00775 virtual ssize_t readData(void * buf,size_t len,char separator=0,timeout_t t=0);
00776
00785 virtual ssize_t writeData(const void* buf,size_t len,timeout_t t=0);
00786
00787
00788 public:
00796 virtual ~Socket();
00797
00801 Socket &operator=(const Socket &from);
00802
00812 InetHostAddress getSender(tpport_t *port = NULL) const;
00813
00823 InetHostAddress getPeer(tpport_t *port = NULL) const;
00824
00832 InetHostAddress getLocal(tpport_t *port = NULL) const;
00833
00844 void setCompletion(bool immediate);
00845
00851 Error setLinger(bool linger);
00852
00860 Error setKeepAlive(bool enable);
00861
00870 Error setTypeOfService(Tos service);
00871
00880 bool isConnected(void) const;
00881
00889 bool isActive(void) const;
00890
00895 bool operator!() const;
00896
00903 inline bool isBroadcast(void) const
00904 {return flags.broadcast;};
00905
00911 inline bool isRouted(void) const
00912 {return flags.route;};
00913
00920 inline Error getErrorNumber(void) const {return errid;}
00921
00928 inline const char *getErrorString(void) const {return errstr;}
00929
00939 virtual bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
00940 };
00941
00974 class UDPSocket : public Socket
00975 {
00976 private:
00977 inline Error setKeepAlive(bool enable)
00978 {return Socket::setKeepAlive(enable);};
00979
00980 protected:
00981 struct sockaddr_in peer;
00982
00983 public:
00987 UDPSocket(void);
00988
00998 UDPSocket(const InetAddress &bind, tpport_t port);
00999
01003 virtual ~UDPSocket();
01004
01012 void setPeer(const InetHostAddress &host, tpport_t port);
01013
01021 Socket::Error getInterfaceIndex(const char *ethX,int& InterfaceIndex);
01022
01031 Socket::Error join(const InetMcastAddress &ia,int InterfaceIndex);
01032
01033
01041 inline int send(const void *buf, size_t len)
01042 {return ::sendto(so, (const char*)buf, len, 0, (struct sockaddr *)&peer, (socklen_t)sizeof(peer));};
01043
01051 inline int receive(void *buf, size_t len)
01052 {return ::recv(so, (char *)buf, len, 0);};
01053
01062 InetHostAddress getPeer(tpport_t *port = NULL) const;
01063
01071 inline int peek(void *buf, size_t len)
01072 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
01073 };
01074
01075
01084 class UDPBroadcast : public UDPSocket
01085 {
01086 private:
01087 void setPeer(const InetHostAddress &ia, tpport_t port) {};
01088
01089 Error setBroadcast(bool enable)
01090 {return Socket::setBroadcast(enable);};
01091
01092 public:
01099 UDPBroadcast(const InetAddress &ia, tpport_t port);
01100
01107 void setPeer(const BroadcastAddress &subnet, tpport_t port);
01108 };
01109
01118 class UDPTransmit : protected UDPSocket
01119 {
01120 private:
01128 Error cConnect(const InetAddress &ia, tpport_t port);
01129
01130 protected:
01134 UDPTransmit();
01135
01147 UDPTransmit(const InetAddress &bind, tpport_t port = 5005);
01148
01158 Error connect(const InetHostAddress &host, tpport_t port);
01159
01169 Error connect(const BroadcastAddress &subnet, tpport_t port);
01170
01178 Error connect(const InetMcastAddress &mgroup, tpport_t port);
01179
01184 Error disconnect(void);
01185
01193 inline int send(const void *buf, int len)
01194 {return ::send(so, (const char *)buf, len, 0);}
01195
01199 inline void endTransmitter(void)
01200 {Socket::endSocket();}
01201
01202
01203
01204
01205
01206
01207 inline SOCKET getTransmitter(void)
01208 {return so;};
01209
01210 inline Error setMulticast(bool enable)
01211 {return Socket::setMulticast(enable);};
01212
01213 inline Error setTimeToLive(unsigned char ttl)
01214 {return Socket::setTimeToLive(ttl);};
01215
01216 public:
01226 inline int transmit(const char *buffer, size_t len)
01227 {return ::send(so, buffer, len, MSG_DONTWAIT);}
01228
01235 inline bool isOutputReady(unsigned long timeout = 0l)
01236 {return Socket::isPending(Socket::pendingOutput, timeout);};
01237
01238
01239 inline Error setRouting(bool enable)
01240 {return Socket::setRouting(enable);};
01241
01242 inline Error setTypeOfService(Tos tos)
01243 {return Socket::setTypeOfService(tos);};
01244
01245 inline Error setBroadcast(bool enable)
01246 {return Socket::setBroadcast(enable);};
01247 };
01248
01257 class UDPReceive : protected UDPSocket
01258 {
01259 protected:
01270 UDPReceive(const InetAddress &bind, tpport_t port);
01271
01281 Error connect(const InetHostAddress &host, tpport_t port);
01282
01287 Error disconnect(void);
01288
01295 bool isPendingReceive(timeout_t timeout)
01296 {return Socket::isPending(Socket::pendingInput, timeout);};
01297
01301 inline void endReceiver(void)
01302 {Socket::endSocket();}
01303
01304 inline SOCKET getReceiver(void) const
01305 {return so;};
01306
01307 inline Error setRouting(bool enable)
01308 {return Socket::setRouting(enable);};
01309
01310 inline Error setMulticast(bool enable)
01311 {return Socket::setMulticast(enable);};
01312
01313 inline Error join(const InetMcastAddress &ia)
01314 {return Socket::join(ia);}
01315
01316 inline Error drop(const InetMcastAddress &ia)
01317 {return Socket::drop(ia);}
01318
01319 public:
01327 inline int receive(void *buf, size_t len)
01328 {return ::recv(so, (char *)buf, len, 0);};
01329
01336 inline bool isInputReady(timeout_t timeout = TIMEOUT_INF)
01337 {return Socket::isPending(Socket::pendingInput, timeout);};
01338 };
01339
01350 class UDPDuplex : public UDPTransmit, public UDPReceive
01351 {
01352 public:
01360 UDPDuplex(const InetAddress &bind, tpport_t port);
01361
01371 Error connect(const InetHostAddress &host, tpport_t port);
01372
01379 Error disconnect(void);
01380 };
01381
01382
01407 class TCPSocket : protected Socket
01408 {
01409 protected:
01421 virtual bool onAccept(const InetHostAddress &ia, tpport_t port)
01422 {return true;};
01423
01424 friend class TCPStream;
01425 friend class SocketPort;
01426 friend class tcpstream;
01427
01428 public:
01440 TCPSocket(const InetAddress &bind, tpport_t port, int backlog = 5);
01441
01450 inline InetHostAddress getRequest(tpport_t *port = NULL) const
01451 {return Socket::getSender(port);};
01452
01456 void reject(void);
01457
01461 inline InetHostAddress getLocal(tpport_t *port = NULL) const
01462 {return Socket::getLocal(port);};
01463
01469 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF)
01470 {return Socket::isPending(Socket::pendingInput, timeout);}
01471
01475 virtual ~TCPSocket()
01476 {endSocket();};
01477 };
01478
01479
01480
01481
01482
01483
01484
01485
01486 #ifdef _MSC_VER
01487 #pragma warning(disable:4275) // disable C4275 warning
01488 #endif
01489
01503 #if defined(__KCC)
01504 #define iostream iostream_withassign
01505 using std::iostream;
01506 #endif
01507 class TCPStream : protected std::streambuf, public Socket, public std::iostream
01508 {
01509 private:
01510 inline Error setBroadcast(bool enable)
01511 {return Socket::setBroadcast(enable);};
01512
01513 inline InetHostAddress getSender(tpport_t *port) const
01514 {return InetHostAddress();};
01515
01516 int doallocate();
01517
01518 friend TCPStream& crlf(TCPStream&);
01519 friend TCPStream& lfcr(TCPStream&);
01520
01521 protected:
01522 timeout_t timeout;
01523 int bufsize;
01524 char *gbuf, *pbuf;
01525
01530 TCPStream(bool throwflag = true);
01531
01538 void allocate(int size);
01539
01544 void endStream(void);
01545
01552 int underflow();
01553
01562 int uflow();
01563
01571 int overflow(int ch);
01572
01581 void connect(const InetHostAddress &host, tpport_t port, int size);
01582
01590 std::iostream *tcp(void)
01591 {return ((std::iostream *)this);};
01592
01593 public:
01604 TCPStream(TCPSocket &server, int size = 512, bool throwflag = true, timeout_t timeout = 0);
01605
01616 TCPStream(const InetHostAddress &host, tpport_t port, int size = 512, bool throwflag = true, timeout_t timeout = 0);
01617
01623 inline void setTimeout(timeout_t to)
01624 {timeout = to;};
01625
01632 TCPStream(const TCPStream &source);
01633
01638 virtual ~TCPStream()
01639 {
01640 try { endStream(); }
01641 catch( ... ) { if ( ! std::uncaught_exception()) throw; }
01642 };
01643
01650 int sync(void);
01651
01659 bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
01660
01668 inline int peek(void *buf, size_t len)
01669 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
01670
01676 int getBufferSize(void) const
01677 {return bufsize;};
01678 };
01679
01688 class tcpstream : public TCPStream
01689 {
01690 public:
01691
01692 tcpstream(const tcpstream &rhs):TCPStream(rhs) {};
01693
01697 tcpstream();
01698
01706 tcpstream(const char *addr, int buffer = 512);
01707
01715 tcpstream(TCPSocket &tcp, int buffer = 512);
01716
01724 void open(const char *addr, int buffer = 512);
01725
01732 void open(TCPSocket &tcp, int buffer = 512);
01733
01737 void close(void);
01738
01742 bool operator!() const;
01743 };
01744
01755 class TCPSession : public TCPStream, public Thread
01756 {
01757 private:
01758 TCPSession(const TCPSession &rhs);
01759 protected:
01772 int waitConnection(timeout_t timeout = TIMEOUT_INF);
01773
01780 CCXX_MEMBER(void) initial(void);
01781
01792 CCXX_MEMBER(void) final(void)
01793 {delete this;};
01794 public:
01805 TCPSession(const InetHostAddress &host,
01806 tpport_t port, int size = 512, int pri = 0, int stack = 0);
01807
01818 TCPSession(TCPSocket &server, int size = 512,
01819 int pri = 0, int stack = 0);
01820 };
01821
01822 extern CCXX_EXPORT(std::ostream&) operator<<(std::ostream &os, const InetAddress &ia);
01823
01824 inline struct in_addr getaddress(const InetAddress &ia)
01825 {return ia.getAddress();}
01826
01827 #if defined(WIN32)
01828
01839 class init_WSA
01840 {
01841 public:
01842 init_WSA();
01843 ~init_WSA();
01844 };
01845
01846 #endif // WIN32
01847
01848 class SocketService;
01849
01869 class SocketPort : public Socket, public TimerPort
01870 {
01871 private:
01872 SocketPort *next, *prev;
01873 SocketService *service;
01874 #ifndef WIN32
01875 struct timeval porttimer;
01876 #ifdef CCXX_USE_POLL
01877 struct pollfd * ufd;
01878 #endif
01879 #else
01880 HANDLE event;
01881 #endif
01882 bool detect_pending;
01883 bool detect_output;
01884 bool detect_disconnect;
01885
01886 friend class SocketService;
01887
01888 protected:
01897 SocketPort(SocketService *svc, TCPSocket &tcp);
01898
01907 SocketPort(SocketService *svc, const InetAddress &ia, tpport_t port);
01908
01922 SocketPort(SocketService *svc, const InetHostAddress &ih, tpport_t port);
01923
01929 void attach( SocketService* svc );
01930
01931
01936 virtual ~SocketPort();
01937
01942 void setDetectPending( bool );
01943
01947 bool getDetectPending( void ) const
01948 { return detect_pending; }
01949
01954 void setDetectOutput( bool );
01955
01959 bool getDetectOutput( void ) const
01960 { return detect_output; }
01961
01966 virtual void expired(void)
01967 {return;};
01968
01973 virtual void pending(void)
01974 {return;};
01975
01980 virtual void output(void)
01981 {return;};
01982
01987 virtual void disconnect(void)
01988 {return;};
01989
02000 Error connect(const InetAddress &ia, tpport_t port);
02001
02011 inline int send(const void *buf, int len)
02012 {return ::send(so, (const char *)buf, len, 0);};
02013
02022 inline int receive(void *buf, size_t len)
02023 {return ::recv(so, (char *)buf, len, 0);};
02024
02033 inline int peek(void *buf, size_t len)
02034 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
02035
02036 public:
02044 void setTimer(timeout_t timeout = 0);
02045
02053 void incTimer(timeout_t timeout);
02054 };
02055
02068 class SocketService : public Thread, private Mutex
02069 {
02070 private:
02071 #ifndef WIN32
02072 fd_set connect;
02073 int iosync[2];
02074 int hiwater;
02075 #else
02076
02077 class Sync;
02078 Sync* sync;
02079 #endif
02080 int count;
02081 SocketPort *first, *last;
02082
02088 void attach(SocketPort *port);
02094 void detach(SocketPort *port);
02095
02099 void run(void);
02100
02101 friend class SocketPort;
02102
02103 protected:
02109 virtual void onUpdate(unsigned char buf)
02110 {return;};
02111
02117 virtual void onEvent(void)
02118 {return;};
02119
02127 virtual void onCallback(SocketPort *port)
02128 {return;};
02129
02130 public:
02141 void update(unsigned char flag = 0xff);
02142
02149 SocketService(int pri = 0);
02150
02155 virtual ~SocketService();
02156
02163 inline int getCount(void) const
02164 {return count;};
02165 };
02166
02167 #ifdef COMMON_STD_EXCEPTION
02168 class SockException : public IOException
02169 {
02170 public:
02171 SockException(std::string str) : IOException(str) {};
02172 };
02173 #endif
02174
02175 #ifdef CCXX_NAMESPACES
02176 };
02177 #endif
02178
02179 #endif
02180