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 #if defined(WIN32)
00190 static MutexCounter counter;
00191 #else
00192 static Mutex mutex;
00193 #endif
00194
00201 bool setIPAddress(const char *host);
00202
00209 void setAddress(const char *host);
00210
00211 public:
00219 InetAddress(const InetAddrValidator *validator = NULL);
00220
00229 InetAddress(struct in_addr addr, const InetAddrValidator *validator = NULL);
00230
00241 InetAddress(const char *address, const InetAddrValidator *validator = NULL);
00242
00246 InetAddress(const InetAddress &rhs);
00247
00251 virtual ~InetAddress();
00252
00259 const char *getHostname(void) const;
00260
00268 bool isInetAddress(void) const;
00269
00277 struct in_addr getAddress(void) const;
00278
00290 struct in_addr getAddress(size_t i) const;
00291
00297 size_t getAddressCount() const { return addr_count; }
00298
00299 InetAddress &operator=(const char *str);
00300 InetAddress &operator=(struct in_addr addr);
00301 InetAddress &operator=(const InetAddress &rhs);
00302
00307 InetAddress &operator=(unsigned long addr);
00308
00309 inline bool operator!() const
00310 {return !isInetAddress();};
00311
00320 bool operator==(const InetAddress &a) const;
00321
00329 bool operator!=(const InetAddress &a) const;
00330 };
00331
00344 class InetMaskAddress : public InetAddress
00345 {
00346 public:
00353 InetMaskAddress(const char *mask);
00354
00365 friend InetHostAddress operator&(const InetHostAddress &addr,
00366 const InetMaskAddress &mask);
00367
00372 InetAddress &operator=(unsigned long addr)
00373 { return InetAddress::operator =(addr); }
00374 };
00375
00383 class InetHostAddress : public InetAddress
00384 {
00385 public:
00398 InetHostAddress(const char *host = NULL);
00399
00407 InetHostAddress(struct in_addr addr);
00408
00413 InetAddress &operator=(unsigned long addr)
00414 { return InetAddress::operator =(addr); }
00415
00420 InetHostAddress &operator&=(const InetMaskAddress &mask);
00421
00422 friend class InetMaskAddress;
00423 friend InetHostAddress operator&(const InetHostAddress &addr,
00424 const InetMaskAddress &mask);
00425 };
00426
00431 class BroadcastAddress : public InetAddress
00432 {
00433 public:
00441 BroadcastAddress(const char *net = "255.255.255.255");
00442 };
00443
00453 class InetMcastAddress: public InetAddress
00454 {
00455 public:
00460 InetMcastAddress();
00461
00468 InetMcastAddress(const struct in_addr address);
00469
00479 InetMcastAddress(const char *address);
00480
00481 private:
00489 static const InetMcastAddrValidator validator;
00490 };
00491
00509 class Socket
00510 {
00511 public:
00512 enum Error
00513 {
00514 errSuccess = 0,
00515 errCreateFailed,
00516 errCopyFailed,
00517 errInput,
00518 errInputInterrupt,
00519 errResourceFailure,
00520 errOutput,
00521 errOutputInterrupt,
00522 errNotConnected,
00523 errConnectRefused,
00524 errConnectRejected,
00525 errConnectTimeout,
00526 errConnectFailed,
00527 errConnectInvalid,
00528 errConnectBusy,
00529 errConnectNoRoute,
00530 errBindingFailed,
00531 errBroadcastDenied,
00532 errRoutingDenied,
00533 errKeepaliveDenied,
00534 errServiceDenied,
00535 errServiceUnavailable,
00536 errMulticastDisabled,
00537 errTimeout,
00538 errNoDelay,
00539 errExtended
00540 };
00541
00542 typedef enum Error Error;
00543
00544 enum Tos
00545 {
00546 tosLowDelay = 0,
00547 tosThroughput,
00548 tosReliability,
00549 tosMinCost,
00550 tosInvalid
00551 };
00552 typedef enum Tos Tos;
00553
00554 enum Pending
00555 {
00556 pendingInput,
00557 pendingOutput,
00558 pendingError
00559 };
00560 typedef enum Pending Pending;
00561
00562 protected:
00563 enum State
00564 {
00565 INITIAL,
00566 AVAILABLE,
00567 BOUND,
00568 CONNECTED,
00569 CONNECTING,
00570 STREAM
00571 };
00572 typedef enum State State;
00573
00574 private:
00575
00576 mutable Error errid;
00577 mutable const char *errstr;
00578
00579 void setSocket(void);
00580 friend SOCKET dupSocket(SOCKET s,Socket::State state);
00581
00582 protected:
00583 mutable struct
00584 {
00585 bool thrown: 1;
00586 bool broadcast: 1;
00587 bool route: 1;
00588 bool keepalive: 1;
00589 bool loopback: 1;
00590 bool multicast: 1;
00591 bool completion: 1;
00592 bool linger: 1;
00593 unsigned ttl: 8;
00594 } flags;
00595
00601 SOCKET so;
00602 State state;
00603
00611 Error error(Error error, char *errstr = NULL) const;
00612
00619 inline void error(char *errstr) const
00620 {error(errExtended, errstr);};
00621
00628 inline void setError(bool enable)
00629 {flags.thrown = !enable;};
00630
00636 void endSocket(void);
00637
00643 Error connectError(void);
00644
00653 Error setBroadcast(bool enable);
00654
00665 Error setMulticast(bool enable);
00666
00674 Error setLoopback(bool enable);
00675
00682 Error setTimeToLive(unsigned char ttl);
00683
00690 Error join(const InetMcastAddress &ia);
00691
00698 Error drop(const InetMcastAddress &ia);
00699
00707 Error setRouting(bool enable);
00708
00709
00716 Error setNoDelay(bool enable);
00717
00729 Socket(int domain, int type, int protocol = 0);
00730
00738 Socket(SOCKET fd);
00739
00747 Socket(const Socket &source);
00748
00758 ssize_t readLine(char *buf, size_t len, timeout_t timeout = 0);
00759
00760 public:
00768 virtual ~Socket();
00769
00773 Socket &operator=(const Socket &from);
00774
00784 InetHostAddress getSender(tpport_t *port = NULL) const;
00785
00795 InetHostAddress getPeer(tpport_t *port = NULL) const;
00796
00804 InetHostAddress getLocal(tpport_t *port = NULL) const;
00805
00816 void setCompletion(bool immediate);
00817
00823 Error setLinger(bool linger);
00824
00832 Error setKeepAlive(bool enable);
00833
00842 Error setTypeOfService(Tos service);
00843
00852 bool isConnected(void) const;
00853
00861 bool isActive(void) const;
00862
00867 bool operator!() const;
00868
00875 inline bool isBroadcast(void) const
00876 {return flags.broadcast;};
00877
00883 inline bool isRouted(void) const
00884 {return flags.route;};
00885
00892 inline Error getErrorNumber(void) const {return errid;}
00893
00900 inline const char *getErrorString(void) const {return errstr;}
00901
00911 virtual bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
00912 };
00913
00946 class UDPSocket : public Socket
00947 {
00948 private:
00949 inline Error setKeepAlive(bool enable)
00950 {return Socket::setKeepAlive(enable);};
00951
00952 protected:
00953 struct sockaddr_in peer;
00954
00955 public:
00959 UDPSocket(void);
00960
00970 UDPSocket(const InetAddress &bind, tpport_t port);
00971
00975 virtual ~UDPSocket();
00976
00984 void setPeer(const InetHostAddress &host, tpport_t port);
00985
00993 inline int send(const void *buf, size_t len)
00994 {return ::sendto(so, (const char*)buf, len, 0, (struct sockaddr *)&peer, (socklen_t)sizeof(peer));};
00995
01003 inline int receive(void *buf, size_t len)
01004 {return ::recv(so, (char *)buf, len, 0);};
01005
01014 InetHostAddress getPeer(tpport_t *port = NULL) const;
01015
01023 inline int peek(void *buf, size_t len)
01024 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
01025 };
01026
01027
01036 class UDPBroadcast : public UDPSocket
01037 {
01038 private:
01039 void setPeer(const InetHostAddress &ia, tpport_t port) {};
01040
01041 Error setBroadcast(bool enable)
01042 {return Socket::setBroadcast(enable);};
01043
01044 public:
01051 UDPBroadcast(const InetAddress &ia, tpport_t port);
01052
01059 void setPeer(const BroadcastAddress &subnet, tpport_t port);
01060 };
01061
01070 class UDPTransmit : protected UDPSocket
01071 {
01072 private:
01080 Error cConnect(const InetAddress &ia, tpport_t port);
01081
01082 protected:
01086 UDPTransmit();
01087
01099 UDPTransmit(const InetAddress &bind, tpport_t port = 5005);
01100
01110 Error connect(const InetHostAddress &host, tpport_t port);
01111
01121 Error connect(const BroadcastAddress &subnet, tpport_t port);
01122
01130 Error connect(const InetMcastAddress &mgroup, tpport_t port);
01131
01136 Error disconnect(void);
01137
01145 inline int send(const void *buf, int len)
01146 {return ::send(so, (const char *)buf, len, 0);}
01147
01151 inline void endTransmitter(void)
01152 {Socket::endSocket();}
01153
01154
01155
01156
01157
01158
01159 inline SOCKET getTransmitter(void)
01160 {return so;};
01161
01162 inline Error setMulticast(bool enable)
01163 {return Socket::setMulticast(enable);};
01164
01165 inline Error setTimeToLive(unsigned char ttl)
01166 {return Socket::setTimeToLive(ttl);};
01167
01168 public:
01178 inline int transmit(const char *buffer, size_t len)
01179 {return ::send(so, buffer, len, MSG_DONTWAIT);}
01180
01187 inline bool isOutputReady(unsigned long timeout = 0l)
01188 {return Socket::isPending(Socket::pendingOutput, timeout);};
01189
01190
01191 inline Error setRouting(bool enable)
01192 {return Socket::setRouting(enable);};
01193
01194 inline Error setTypeOfService(Tos tos)
01195 {return Socket::setTypeOfService(tos);};
01196
01197 inline Error setBroadcast(bool enable)
01198 {return Socket::setBroadcast(enable);};
01199 };
01200
01209 class UDPReceive : protected UDPSocket
01210 {
01211 protected:
01222 UDPReceive(const InetAddress &bind, tpport_t port);
01223
01233 Error connect(const InetHostAddress &host, tpport_t port);
01234
01239 Error disconnect(void);
01240
01247 bool isPendingReceive(timeout_t timeout)
01248 {return Socket::isPending(Socket::pendingInput, timeout);};
01249
01253 inline void endReceiver(void)
01254 {Socket::endSocket();}
01255
01256 inline SOCKET getReceiver(void)
01257 {return so;};
01258
01259 inline Error setRouting(bool enable)
01260 {return Socket::setRouting(enable);};
01261
01262 inline Error setMulticast(bool enable)
01263 {return Socket::setMulticast(enable);};
01264
01265 inline Error join(const InetMcastAddress &ia)
01266 {return Socket::join(ia);}
01267
01268 inline Error drop(const InetMcastAddress &ia)
01269 {return Socket::drop(ia);}
01270
01271 public:
01279 inline int receive(void *buf, size_t len)
01280 {return ::recv(so, (char *)buf, len, 0);};
01281
01288 inline bool isInputReady(timeout_t timeout = TIMEOUT_INF)
01289 {return Socket::isPending(Socket::pendingInput, timeout);};
01290 };
01291
01302 class UDPDuplex : public UDPTransmit, public UDPReceive
01303 {
01304 public:
01312 UDPDuplex(const InetAddress &bind, tpport_t port);
01313
01323 Error connect(const InetHostAddress &host, tpport_t port);
01324
01331 Error disconnect(void);
01332 };
01333
01334
01359 class TCPSocket : protected Socket
01360 {
01361 protected:
01373 virtual bool onAccept(const InetHostAddress &ia, tpport_t port)
01374 {return true;};
01375
01376 friend class TCPStream;
01377 friend class SocketPort;
01378 friend class tcpstream;
01379
01380 public:
01392 TCPSocket(const InetAddress &bind, tpport_t port, int backlog = 5);
01393
01402 inline InetHostAddress getRequest(tpport_t *port = NULL) const
01403 {return Socket::getSender(port);};
01404
01408 void reject(void);
01409
01413 inline InetHostAddress getLocal(tpport_t *port = NULL) const
01414 {return Socket::getLocal(port);};
01415
01419 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF)
01420 {return Socket::isPending(Socket::pendingInput, timeout);}
01421
01425 virtual ~TCPSocket()
01426 {endSocket();};
01427 };
01428
01429
01430
01431
01432
01433
01434
01435
01436 #ifdef _MSC_VER
01437 #pragma warning(disable:4275) // disable C4275 warning
01438 #endif
01439
01453 #if defined(__KCC)
01454 #define iostream iostream_withassign
01455 using std::iostream;
01456 #endif
01457 class TCPStream : protected std::streambuf, public Socket, public std::iostream
01458 {
01459 private:
01460 inline Error setBroadcast(bool enable)
01461 {return Socket::setBroadcast(enable);};
01462
01463 inline InetHostAddress getSender(tpport_t *port) const
01464 {return InetHostAddress();};
01465
01466 int doallocate();
01467
01468 friend TCPStream& crlf(TCPStream&);
01469 friend TCPStream& lfcr(TCPStream&);
01470
01471 protected:
01472 timeout_t timeout;
01473 int bufsize;
01474 char *gbuf, *pbuf;
01475
01480 TCPStream(bool throwflag = true);
01481
01488 void allocate(int size);
01489
01494 void endStream(void);
01495
01502 int underflow();
01503
01512 int uflow();
01513
01521 int overflow(int ch);
01522
01531 void connect(const InetHostAddress &host, tpport_t port, int size);
01532
01540 std::iostream *tcp(void)
01541 {return ((std::iostream *)this);};
01542
01543 public:
01554 TCPStream(TCPSocket &server, int size = 512, bool throwflag = true, timeout_t timeout = 0);
01555
01566 TCPStream(const InetHostAddress &host, tpport_t port, int size = 512, bool throwflag = true, timeout_t timeout = 0);
01567
01573 inline void setTimeout(timeout_t to)
01574 {timeout = to;};
01575
01582 TCPStream(const TCPStream &source);
01583
01588 virtual ~TCPStream()
01589 {endStream();};
01590
01597 int sync(void);
01598
01606 bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
01607
01613 int getBufferSize(void) const
01614 {return bufsize;};
01615 };
01616
01625 class tcpstream : public TCPStream
01626 {
01627 public:
01628
01629 tcpstream(const tcpstream &rhs):TCPStream(rhs) {};
01630
01634 tcpstream();
01635
01643 tcpstream(const char *addr, int buffer = 512);
01644
01652 tcpstream(TCPSocket &tcp, int buffer = 512);
01653
01661 void open(const char *addr, int buffer = 512);
01662
01669 void open(TCPSocket &tcp, int buffer = 512);
01670
01674 void close(void);
01675
01679 bool operator!() const;
01680 };
01681
01692 class TCPSession : public TCPStream, public Thread
01693 {
01694 private:
01695 TCPSession(const TCPSession &rhs);
01696 protected:
01709 int waitConnection(timeout_t timeout = TIMEOUT_INF);
01710
01717 CCXX_MEMBER(void) initial(void);
01718
01724 CCXX_MEMBER(void) final(void)
01725 {delete this;};
01726 public:
01737 TCPSession(const InetHostAddress &host,
01738 tpport_t port, int size = 512, int pri = 0, int stack = 0);
01739
01750 TCPSession(TCPSocket &server, int size = 512,
01751 int pri = 0, int stack = 0);
01752 };
01753
01754 extern CCXX_EXPORT(std::ostream&) operator<<(std::ostream &os, const InetAddress &ia);
01755
01756 inline struct in_addr getaddress(const InetAddress &ia)
01757 {return ia.getAddress();}
01758
01759 #if defined(WIN32)
01760
01771 class init_WSA
01772 {
01773 public:
01774 init_WSA();
01775 ~init_WSA();
01776 };
01777
01778 #endif // WIN32
01779
01780 class SocketService;
01781
01801 class SocketPort : public Socket, public TimerPort
01802 {
01803 private:
01804 SocketPort *next, *prev;
01805 SocketService *service;
01806 #ifndef WIN32
01807 struct timeval porttimer;
01808 #ifdef CCXX_USE_POLL
01809 struct pollfd * ufd;
01810 #endif
01811 #else
01812 HANDLE event;
01813 #endif
01814 bool detect_pending;
01815 bool detect_output;
01816 bool detect_disconnect;
01817
01818 friend class SocketService;
01819
01820 protected:
01829 SocketPort(SocketService *svc, TCPSocket &tcp);
01830
01839 SocketPort(SocketService *svc, const InetAddress &ia, tpport_t port);
01840
01854 SocketPort(SocketService *svc, const InetHostAddress &ih, tpport_t port);
01855
01861 void attach( SocketService* svc );
01862
01863
01868 virtual ~SocketPort();
01869
01874 void setDetectPending( bool );
01875
01879 bool getDetectPending( void ) const
01880 { return detect_pending; }
01881
01886 void setDetectOutput( bool );
01887
01891 bool getDetectOutput( void ) const
01892 { return detect_output; }
01893
01898 virtual void expired(void)
01899 {return;};
01900
01905 virtual void pending(void)
01906 {return;};
01907
01912 virtual void output(void)
01913 {return;};
01914
01919 virtual void disconnect(void)
01920 {return;};
01921
01932 Error connect(const InetAddress &ia, tpport_t port);
01933
01943 inline int send(const void *buf, int len)
01944 {return ::send(so, (const char *)buf, len, 0);};
01945
01954 inline int receive(void *buf, size_t len)
01955 {return ::recv(so, (char *)buf, len, 0);};
01956
01965 inline int peek(void *buf, size_t len)
01966 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
01967
01968 public:
01976 void setTimer(timeout_t timeout = 0);
01977
01985 void incTimer(timeout_t timeout);
01986 };
01987
02000 class SocketService : public Thread, private Mutex
02001 {
02002 private:
02003 #ifndef WIN32
02004 fd_set connect;
02005 int iosync[2];
02006 int hiwater;
02007 #else
02008
02009 class Sync;
02010 Sync* sync;
02011 #endif
02012 int count;
02013 SocketPort *first, *last;
02014
02020 void attach(SocketPort *port);
02026 void detach(SocketPort *port);
02027
02031 void run(void);
02032
02033 friend class SocketPort;
02034
02035 protected:
02041 virtual void onUpdate(unsigned char buf)
02042 {return;};
02043
02049 virtual void onEvent(void)
02050 {return;};
02051
02059 virtual void onCallback(SocketPort *port)
02060 {return;};
02061
02062 public:
02073 void update(unsigned char flag = 0xff);
02074
02081 SocketService(int pri = 0);
02082
02087 virtual ~SocketService();
02088
02095 inline int getCount(void) const
02096 {return count;};
02097 };
02098
02099 #ifdef COMMON_STD_EXCEPTION
02100 class SockException : public IOException
02101 {
02102 public:
02103 SockException(std::string str) : IOException(str) {};
02104 };
02105 #endif
02106
02107 #ifdef CCXX_NAMESPACES
02108 };
02109 #endif
02110
02111 #endif
02112