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_MISSING_H_
00050 #include <cc++/missing.h>
00051 #endif
00052
00053 #ifndef CCXX_THREAD_H_
00054 #include <cc++/thread.h>
00055 #endif
00056
00057 #ifndef CCXX_EXCEPTION_H_
00058 #include <cc++/exception.h>
00059 #endif
00060
00061 #if defined(WIN32) && !defined(__CYGWIN32__)
00062 #define __WINSOCK__
00063 #include <winsock2.h>
00064 #include <io.h>
00065 #define TIMEOUT_INF ~((timeout_t) 0)
00066 typedef int socklen_t;
00067 #else
00068 #define INVALID_SOCKET -1
00069 typedef int SOCKET;
00070 #endif
00071
00072 #ifndef MSG_DONTWAIT
00073 #define MSG_DONTWAIT 0
00074 #endif
00075
00076 #ifdef CCXX_NAMESPACES
00077 namespace ost {
00078 #endif
00079
00080
00081
00085 typedef unsigned short tpport_t;
00086
00087 class __EXPORT InetHostAddress;
00088 class __EXPORT SocketPort;
00089 class __EXPORT SocketService;
00090
00099 class __EXPORT InetAddrValidator
00100 {
00101 public:
00105 InetAddrValidator() { };
00106
00111 virtual void
00112 operator()(const in_addr address) const = 0;
00113 };
00114
00123 class __EXPORT InetMcastAddrValidator: public InetAddrValidator
00124 {
00125 public:
00129 InetMcastAddrValidator(){};
00130
00135 inline void
00136 operator()(const in_addr address) const;
00137 private:
00138 #if __BYTE_ORDER == __BIG_ENDIAN
00139 enum {
00140 MCAST_VALID_MASK = 0xF0000000,
00141 MCAST_VALID_VALUE = 0xE0000000
00142 };
00143 #else
00144 enum {
00145 MCAST_VALID_MASK = 0x000000F0,
00146 MCAST_VALID_VALUE = 0x000000E0
00147 };
00148 #endif
00149 };
00150
00165 class __EXPORT InetAddress
00166 {
00167 private:
00168
00169
00170
00171
00172
00173 const InetAddrValidator *validator;
00174
00175 protected:
00176 struct in_addr * ipaddr;
00177 size_t addr_count;
00178 mutable char* hostname;
00179 #if defined(WIN32)
00180 static MutexCounter counter;
00181 #else
00182 static Mutex mutex;
00183 #endif
00184
00191 bool setIPAddress(const char *host);
00192
00199 void setAddress(const char *host);
00200
00201 public:
00209 InetAddress(const InetAddrValidator *validator = NULL);
00210
00219 InetAddress(struct in_addr addr, const InetAddrValidator *validator = NULL);
00220
00231 InetAddress(const char *address, const InetAddrValidator *validator = NULL);
00232
00236 InetAddress(const InetAddress &rhs);
00237
00241 virtual ~InetAddress();
00242
00249 const char *getHostname(void) const;
00250
00258 bool isInetAddress(void) const;
00259
00267 struct in_addr getAddress(void) const;
00268
00280 struct in_addr getAddress(size_t i) const;
00281
00287 size_t getAddressCount() const { return addr_count; }
00288
00289 InetAddress &operator=(const char *str);
00290 InetAddress &operator=(struct in_addr addr);
00291 InetAddress &operator=(const InetAddress &rhs);
00292
00297 InetAddress &operator=(unsigned long addr);
00298
00299 inline InetAddress &operator=(unsigned int addr)
00300 {return *this = (unsigned long) addr; }
00301
00302 inline bool operator!() const
00303 {return !isInetAddress();};
00304
00313 bool operator==(const InetAddress &a) const;
00314
00322 bool operator!=(const InetAddress &a) const;
00323 };
00324
00337 class __EXPORT InetMaskAddress : public InetAddress
00338 {
00339 public:
00346 InetMaskAddress(const char *mask);
00347
00358 friend __EXPORT InetHostAddress operator&(const InetHostAddress &addr,
00359 const InetMaskAddress &mask);
00360
00365 InetAddress &operator=(unsigned long addr)
00366 { return InetAddress::operator =(addr); }
00367 };
00368
00376 class __EXPORT InetHostAddress : public InetAddress
00377 {
00378 public:
00391 InetHostAddress(const char *host = NULL);
00392
00400 InetHostAddress(struct in_addr addr);
00401
00406 InetAddress &operator=(unsigned long addr)
00407 { return InetAddress::operator =(addr); }
00408
00413 InetHostAddress &operator&=(const InetMaskAddress &mask);
00414
00415 friend class __EXPORT InetMaskAddress;
00416 friend __EXPORT InetHostAddress operator&(const InetHostAddress &addr,
00417 const InetMaskAddress &mask);
00418 };
00419
00424 class __EXPORT BroadcastAddress : public InetAddress
00425 {
00426 public:
00434 BroadcastAddress(const char *net = "255.255.255.255");
00435 };
00436
00446 class __EXPORT InetMcastAddress: public InetAddress
00447 {
00448 public:
00453 InetMcastAddress();
00454
00461 InetMcastAddress(const struct in_addr address);
00462
00472 InetMcastAddress(const char *address);
00473
00474 private:
00482 static const InetMcastAddrValidator validator;
00483 };
00484
00502 class __EXPORT Socket
00503 {
00504 public:
00505 enum Error
00506 {
00507 errSuccess = 0,
00508 errCreateFailed,
00509 errCopyFailed,
00510 errInput,
00511 errInputInterrupt,
00512 errResourceFailure,
00513 errOutput,
00514 errOutputInterrupt,
00515 errNotConnected,
00516 errConnectRefused,
00517 errConnectRejected,
00518 errConnectTimeout,
00519 errConnectFailed,
00520 errConnectInvalid,
00521 errConnectBusy,
00522 errConnectNoRoute,
00523 errBindingFailed,
00524 errBroadcastDenied,
00525 errRoutingDenied,
00526 errKeepaliveDenied,
00527 errServiceDenied,
00528 errServiceUnavailable,
00529 errMulticastDisabled,
00530 errTimeout,
00531 errNoDelay,
00532 errExtended
00533 };
00534
00535 typedef enum Error Error;
00536
00537 enum Tos
00538 {
00539 tosLowDelay = 0,
00540 tosThroughput,
00541 tosReliability,
00542 tosMinCost,
00543 tosInvalid
00544 };
00545 typedef enum Tos Tos;
00546
00547 enum Pending
00548 {
00549 pendingInput,
00550 pendingOutput,
00551 pendingError
00552 };
00553 typedef enum Pending Pending;
00554
00555 protected:
00556 enum State
00557 {
00558 INITIAL,
00559 AVAILABLE,
00560 BOUND,
00561 CONNECTED,
00562 CONNECTING,
00563 STREAM
00564 };
00565 typedef enum State State;
00566
00567 private:
00568
00569 mutable Error errid;
00570 mutable const char *errstr;
00571 mutable long syserr;
00572
00573 void setSocket(void);
00574 friend SOCKET dupSocket(SOCKET s,Socket::State state);
00575
00576 protected:
00577 mutable struct
00578 {
00579 bool thrown: 1;
00580 bool broadcast: 1;
00581 bool route: 1;
00582 bool keepalive: 1;
00583 bool loopback: 1;
00584 bool multicast: 1;
00585 bool completion: 1;
00586 bool linger: 1;
00587 unsigned ttl: 8;
00588 } flags;
00589
00595 SOCKET so;
00596 State state;
00597
00606 Error error(Error error, char *errstr = NULL, long systemError = 0) const;
00607
00614 inline void error(char *errstr) const
00615 {error(errExtended, errstr);};
00616
00623 inline void setError(bool enable)
00624 {flags.thrown = !enable;};
00625
00631 void endSocket(void);
00632
00638 Error connectError(void);
00639
00648 Error setBroadcast(bool enable);
00649
00660 Error setMulticast(bool enable);
00661
00669 Error setLoopback(bool enable);
00670
00677 Error setTimeToLive(unsigned char ttl);
00678
00685 Error join(const InetMcastAddress &ia);
00686
00693 Error drop(const InetMcastAddress &ia);
00694
00702 Error setRouting(bool enable);
00703
00704
00711 Error setNoDelay(bool enable);
00712
00724 Socket(int domain, int type, int protocol = 0);
00725
00733 Socket(SOCKET fd);
00734
00742 Socket(const Socket &source);
00743
00753 ssize_t readLine(char *buf, size_t len, timeout_t timeout = 0);
00754
00766 virtual ssize_t readData(void * buf,size_t len,char separator=0,timeout_t t=0);
00767
00776 virtual ssize_t writeData(const void* buf,size_t len,timeout_t t=0);
00777
00778
00779 public:
00787 virtual ~Socket();
00788
00792 Socket &operator=(const Socket &from);
00793
00803 InetHostAddress getSender(tpport_t *port = NULL) const;
00804
00814 InetHostAddress getPeer(tpport_t *port = NULL) const;
00815
00823 InetHostAddress getLocal(tpport_t *port = NULL) const;
00824
00835 void setCompletion(bool immediate);
00836
00842 Error setLinger(bool linger);
00843
00851 Error setKeepAlive(bool enable);
00852
00861 Error setTypeOfService(Tos service);
00862
00871 bool isConnected(void) const;
00872
00880 bool isActive(void) const;
00881
00886 bool operator!() const;
00887
00894 inline bool isBroadcast(void) const
00895 {return flags.broadcast;};
00896
00902 inline bool isRouted(void) const
00903 {return flags.route;};
00904
00911 inline Error getErrorNumber(void) const {return errid;}
00912
00919 inline const char *getErrorString(void) const {return errstr;}
00920
00921 inline long getSystemError(void) const {return syserr;}
00922
00923 const char *getSystemErrorString(void) const;
00924
00934 virtual bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
00935 };
00936
00969 class __EXPORT UDPSocket : public Socket
00970 {
00971 private:
00972 inline Error setKeepAlive(bool enable)
00973 {return Socket::setKeepAlive(enable);};
00974
00975 protected:
00976 struct sockaddr_in peer;
00977
00978 public:
00982 UDPSocket(void);
00983
00993 UDPSocket(const InetAddress &bind, tpport_t port);
00994
00998 virtual ~UDPSocket();
00999
01007 void setPeer(const InetHostAddress &host, tpport_t port);
01008
01016 Socket::Error getInterfaceIndex(const char *ethX,int& InterfaceIndex);
01017
01026 Socket::Error join(const InetMcastAddress &ia,int InterfaceIndex);
01027
01028
01036 inline int send(const void *buf, size_t len)
01037 {return ::sendto(so, (const char*)buf, len, 0, (struct sockaddr *)&peer, (socklen_t)sizeof(peer));};
01038
01046 inline int receive(void *buf, size_t len)
01047 {return ::recv(so, (char *)buf, len, 0);};
01048
01057 InetHostAddress getPeer(tpport_t *port = NULL) const;
01058
01066 inline int peek(void *buf, size_t len)
01067 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
01068
01073 Error disconnect(void);
01074 };
01075
01076
01085 class __EXPORT UDPBroadcast : public UDPSocket
01086 {
01087 private:
01088 void setPeer(const InetHostAddress &ia, tpport_t port) {};
01089
01090 Error setBroadcast(bool enable)
01091 {return Socket::setBroadcast(enable);};
01092
01093 public:
01100 UDPBroadcast(const InetAddress &ia, tpport_t port);
01101
01108 void setPeer(const BroadcastAddress &subnet, tpport_t port);
01109 };
01110
01119 class __EXPORT UDPTransmit : protected UDPSocket
01120 {
01121 private:
01129 Error cConnect(const InetAddress &ia, tpport_t port);
01130
01131 protected:
01135 UDPTransmit();
01136
01148 UDPTransmit(const InetAddress &bind, tpport_t port = 5005);
01149
01159 Error connect(const InetHostAddress &host, tpport_t port);
01160
01170 Error connect(const BroadcastAddress &subnet, tpport_t port);
01171
01179 Error connect(const InetMcastAddress &mgroup, tpport_t port);
01180
01188 inline int send(const void *buf, int len)
01189 {return ::send(so, (const char *)buf, len, 0);}
01190
01194 inline void endTransmitter(void)
01195 {Socket::endSocket();}
01196
01197
01198
01199
01200
01201
01202 inline SOCKET getTransmitter(void)
01203 {return so;};
01204
01205 inline Error setMulticast(bool enable)
01206 {return Socket::setMulticast(enable);};
01207
01208 inline Error setTimeToLive(unsigned char ttl)
01209 {return Socket::setTimeToLive(ttl);};
01210
01211 public:
01221 inline int transmit(const char *buffer, size_t len)
01222 {return ::send(so, buffer, len, MSG_DONTWAIT);}
01223
01230 inline bool isOutputReady(unsigned long timeout = 0l)
01231 {return Socket::isPending(Socket::pendingOutput, timeout);};
01232
01233
01234 inline Error setRouting(bool enable)
01235 {return Socket::setRouting(enable);};
01236
01237 inline Error setTypeOfService(Tos tos)
01238 {return Socket::setTypeOfService(tos);};
01239
01240 inline Error setBroadcast(bool enable)
01241 {return Socket::setBroadcast(enable);};
01242 };
01243
01252 class __EXPORT UDPReceive : protected UDPSocket
01253 {
01254 protected:
01265 UDPReceive(const InetAddress &bind, tpport_t port);
01266
01276 Error connect(const InetHostAddress &host, tpport_t port);
01277
01284 bool isPendingReceive(timeout_t timeout)
01285 {return Socket::isPending(Socket::pendingInput, timeout);};
01286
01290 inline void endReceiver(void)
01291 {Socket::endSocket();}
01292
01293 inline SOCKET getReceiver(void) const
01294 {return so;};
01295
01296 inline Error setRouting(bool enable)
01297 {return Socket::setRouting(enable);};
01298
01299 inline Error setMulticast(bool enable)
01300 {return Socket::setMulticast(enable);};
01301
01302 inline Error join(const InetMcastAddress &ia)
01303 {return Socket::join(ia);}
01304
01305 inline Error drop(const InetMcastAddress &ia)
01306 {return Socket::drop(ia);}
01307
01308 public:
01316 inline int receive(void *buf, size_t len)
01317 {return ::recv(so, (char *)buf, len, 0);};
01318
01325 inline bool isInputReady(timeout_t timeout = TIMEOUT_INF)
01326 {return Socket::isPending(Socket::pendingInput, timeout);};
01327 };
01328
01339 class __EXPORT UDPDuplex : public UDPTransmit, public UDPReceive
01340 {
01341 public:
01349 UDPDuplex(const InetAddress &bind, tpport_t port);
01350
01360 Error connect(const InetHostAddress &host, tpport_t port);
01361
01368 Error disconnect(void);
01369 };
01370
01371
01396 class __EXPORT TCPSocket : protected Socket
01397 {
01398 protected:
01410 virtual bool onAccept(const InetHostAddress &ia, tpport_t port)
01411 {return true;};
01412
01413 friend class TCPStream;
01414 friend class SocketPort;
01415 friend class tcpstream;
01416 friend class SimpleTCPStream;
01417
01418 public:
01430 TCPSocket(const InetAddress &bind, tpport_t port, int backlog = 5);
01431
01440 inline InetHostAddress getRequest(tpport_t *port = NULL) const
01441 {return Socket::getSender(port);};
01442
01446 void reject(void);
01447
01451 inline InetHostAddress getLocal(tpport_t *port = NULL) const
01452 {return Socket::getLocal(port);};
01453
01459 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF)
01460 {return Socket::isPending(Socket::pendingInput, timeout);}
01461
01465 virtual ~TCPSocket()
01466 {endSocket();};
01467 };
01468
01469
01470
01471
01472
01473
01474
01475
01476 #ifdef _MSC_VER
01477 #pragma warning(disable:4275) // disable C4275 warning
01478 #endif
01479
01493 class __EXPORT TCPStream : protected std::streambuf, public Socket, public std::iostream
01494 {
01495 private:
01496 inline Error setBroadcast(bool enable)
01497 {return Socket::setBroadcast(enable);};
01498
01499 inline InetHostAddress getSender(tpport_t *port) const
01500 {return InetHostAddress();};
01501
01502 int doallocate();
01503
01504 friend TCPStream& crlf(TCPStream&);
01505 friend TCPStream& lfcr(TCPStream&);
01506
01507 protected:
01508 timeout_t timeout;
01509 int bufsize;
01510 char *gbuf, *pbuf;
01511
01516 TCPStream(bool throwflag = true);
01517
01524 void allocate(int size);
01525
01530 void endStream(void);
01531
01538 int underflow();
01539
01548 int uflow();
01549
01557 int overflow(int ch);
01558
01567 void connect(const InetHostAddress &host, tpport_t port, int size);
01568
01576 std::iostream *tcp(void)
01577 {return ((std::iostream *)this);};
01578
01579 public:
01590 TCPStream(TCPSocket &server, int size = 512, bool throwflag = true, timeout_t timeout = 0);
01591
01602 TCPStream(const InetHostAddress &host, tpport_t port, int size = 512, bool throwflag = true, timeout_t timeout = 0);
01603
01609 inline void setTimeout(timeout_t to)
01610 {timeout = to;};
01611
01618 TCPStream(const TCPStream &source);
01619
01624 virtual ~TCPStream()
01625 {
01626 #ifdef CCXX_EXCEPTIONS
01627 try { endStream(); }
01628 catch( ... ) { if ( ! std::uncaught_exception()) throw; }
01629 #else
01630 endStream();
01631 #endif
01632 };
01633
01640 int sync(void);
01641
01642 #ifdef HAVE_SNPRINTF
01643
01649 int printf(const char *format, ...);
01650 #endif
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 __EXPORT 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 __EXPORT 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 void initial(void);
01781
01792 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 __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
01838 class init_WSA
01839 {
01840 public:
01841 init_WSA();
01842 ~init_WSA();
01843 };
01844
01845 #endif // WIN32
01846
01847 class __EXPORT SimpleTCPStream;
01848
01860 class __EXPORT SimpleTCPStream : protected Socket
01861 {
01862 private:
01863
01864 inline InetHostAddress getSender(tpport_t *port) const
01865 { return InetHostAddress(); };
01866
01867 protected:
01872 SimpleTCPStream();
01873
01878 void endStream(void);
01879
01888 void Connect(const InetHostAddress &host, tpport_t port, int size);
01889
01890
01891 public:
01900 SimpleTCPStream(TCPSocket &server, int size = 512);
01901
01910 SimpleTCPStream(const InetHostAddress &host, tpport_t port, int size = 512);
01911
01917 SimpleTCPStream(const SimpleTCPStream &source);
01918
01923 virtual ~SimpleTCPStream() { endStream(); };
01924
01936 bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
01937
01938 void flush() {}
01939
01951 int read(char *bytes,int length, timeout_t timeout = 0);
01952
01964 int write(const char *bytes,int length, timeout_t timeout = 0);
01965
01979 int peek(char *bytes,int length, timeout_t timeout = 0);
01980
01981 };
01982
01983 class __EXPORT SocketService;
01984
02004 class __EXPORT SocketPort : public Socket, public TimerPort
02005 {
02006 private:
02007 SocketPort *next, *prev;
02008 SocketService *service;
02009 #ifndef WIN32
02010 struct timeval porttimer;
02011 #ifdef USE_POLL
02012 struct pollfd * ufd;
02013 #endif
02014 #else
02015 HANDLE event;
02016 #endif
02017 bool detect_pending;
02018 bool detect_output;
02019 bool detect_disconnect;
02020
02021 friend class SocketService;
02022
02023 protected:
02032 SocketPort(SocketService *svc, TCPSocket &tcp);
02033
02042 SocketPort(SocketService *svc, const InetAddress &ia, tpport_t port);
02043
02057 SocketPort(SocketService *svc, const InetHostAddress &ih, tpport_t port);
02058
02064 void attach( SocketService* svc );
02065
02066
02071 virtual ~SocketPort();
02072
02077 void setDetectPending( bool );
02078
02082 bool getDetectPending( void ) const
02083 { return detect_pending; }
02084
02089 void setDetectOutput( bool );
02090
02094 bool getDetectOutput( void ) const
02095 { return detect_output; }
02096
02101 virtual void expired(void)
02102 {return;};
02103
02108 virtual void pending(void)
02109 {return;};
02110
02115 virtual void output(void)
02116 {return;};
02117
02122 virtual void disconnect(void)
02123 {return;};
02124
02135 Error connect(const InetAddress &ia, tpport_t port);
02136
02146 inline int send(const void *buf, int len)
02147 {return ::send(so, (const char *)buf, len, 0);};
02148
02157 inline int receive(void *buf, size_t len)
02158 {return ::recv(so, (char *)buf, len, 0);};
02159
02168 inline int peek(void *buf, size_t len)
02169 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
02170
02171 public:
02179 void setTimer(timeout_t timeout = 0);
02180
02188 void incTimer(timeout_t timeout);
02189 };
02190
02203 class __EXPORT SocketService : public Thread, private Mutex
02204 {
02205 private:
02206 #ifndef WIN32
02207 fd_set connect;
02208 int iosync[2];
02209 int hiwater;
02210 #else
02211
02212 class Sync;
02213 Sync* sync;
02214 #endif
02215 int count;
02216 SocketPort *first, *last;
02217
02223 void attach(SocketPort *port);
02229 void detach(SocketPort *port);
02230
02234 void run(void);
02235
02236 friend class SocketPort;
02237
02238 protected:
02244 virtual void onUpdate(unsigned char buf)
02245 {return;};
02246
02252 virtual void onEvent(void)
02253 {return;};
02254
02262 virtual void onCallback(SocketPort *port)
02263 {return;};
02264
02265 public:
02276 void update(unsigned char flag = 0xff);
02277
02284 SocketService(int pri = 0, size_t stack = 0, const char *id = NULL);
02285
02290 virtual ~SocketService();
02291
02298 inline int getCount(void) const
02299 {return count;};
02300 };
02301
02302 #ifdef COMMON_STD_EXCEPTION
02303 class __EXPORT SockException : public IOException
02304 {
02305 private:
02306 Socket::Error _socketError;
02307
02308 public:
02309 SockException(String str, Socket::Error socketError, long systemError = 0) :
02310 IOException(str, systemError), _socketError(socketError) {};
02311
02312 inline Socket::Error getSocketError() const
02313 { return _socketError; }
02314 };
02315 #endif
02316
02317 #ifdef CCXX_NAMESPACES
02318 };
02319 #endif
02320
02321 #endif
02322