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 try { endStream(); }
01627 catch( ... ) { if ( ! std::uncaught_exception()) throw; }
01628 };
01629
01636 int sync(void);
01637
01638 #ifdef HAVE_SNPRINTF
01639
01645 int printf(const char *format, ...);
01646 #endif
01647
01655 bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
01656
01664 inline int peek(void *buf, size_t len)
01665 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
01666
01672 int getBufferSize(void) const
01673 {return bufsize;};
01674 };
01675
01684 class __EXPORT tcpstream : public TCPStream
01685 {
01686 public:
01687
01688 tcpstream(const tcpstream &rhs):TCPStream(rhs) {};
01689
01693 tcpstream();
01694
01702 tcpstream(const char *addr, int buffer = 512);
01703
01711 tcpstream(TCPSocket &tcp, int buffer = 512);
01712
01720 void open(const char *addr, int buffer = 512);
01721
01728 void open(TCPSocket &tcp, int buffer = 512);
01729
01733 void close(void);
01734
01738 bool operator!() const;
01739 };
01740
01751 class __EXPORT TCPSession : public TCPStream, public Thread
01752 {
01753 private:
01754 TCPSession(const TCPSession &rhs);
01755 protected:
01768 int waitConnection(timeout_t timeout = TIMEOUT_INF);
01769
01776 void initial(void);
01777
01788 void final(void)
01789 {delete this;};
01790 public:
01801 TCPSession(const InetHostAddress &host,
01802 tpport_t port, int size = 512, int pri = 0, int stack = 0);
01803
01814 TCPSession(TCPSocket &server, int size = 512,
01815 int pri = 0, int stack = 0);
01816 };
01817
01818 extern __EXPORT std::ostream& operator<<(std::ostream &os, const InetAddress &ia);
01819
01820 inline struct in_addr getaddress(const InetAddress &ia)
01821 {return ia.getAddress();}
01822
01823 #if defined(WIN32)
01824
01834 class init_WSA
01835 {
01836 public:
01837 init_WSA();
01838 ~init_WSA();
01839 };
01840
01841 #endif // WIN32
01842
01843 class __EXPORT SimpleTCPStream;
01844
01856 class __EXPORT SimpleTCPStream : protected Socket
01857 {
01858 private:
01859
01860 inline InetHostAddress getSender(tpport_t *port) const
01861 { return InetHostAddress(); };
01862
01863 protected:
01868 SimpleTCPStream();
01869
01874 void endStream(void);
01875
01884 void Connect(const InetHostAddress &host, tpport_t port, int size);
01885
01886
01887 public:
01896 SimpleTCPStream(TCPSocket &server, int size = 512);
01897
01906 SimpleTCPStream(const InetHostAddress &host, tpport_t port, int size = 512);
01907
01913 SimpleTCPStream(const SimpleTCPStream &source);
01914
01919 virtual ~SimpleTCPStream() { endStream(); };
01920
01932 bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
01933
01934 void flush() {}
01935
01947 int read(char *bytes,int length, timeout_t timeout = 0);
01948
01960 int write(const char *bytes,int length, timeout_t timeout = 0);
01961
01975 int peek(char *bytes,int length, timeout_t timeout = 0);
01976
01977 };
01978
01979 class __EXPORT SocketService;
01980
02000 class __EXPORT SocketPort : public Socket, public TimerPort
02001 {
02002 private:
02003 SocketPort *next, *prev;
02004 SocketService *service;
02005 #ifndef WIN32
02006 struct timeval porttimer;
02007 #ifdef USE_POLL
02008 struct pollfd * ufd;
02009 #endif
02010 #else
02011 HANDLE event;
02012 #endif
02013 bool detect_pending;
02014 bool detect_output;
02015 bool detect_disconnect;
02016
02017 friend class SocketService;
02018
02019 protected:
02028 SocketPort(SocketService *svc, TCPSocket &tcp);
02029
02038 SocketPort(SocketService *svc, const InetAddress &ia, tpport_t port);
02039
02053 SocketPort(SocketService *svc, const InetHostAddress &ih, tpport_t port);
02054
02060 void attach( SocketService* svc );
02061
02062
02067 virtual ~SocketPort();
02068
02073 void setDetectPending( bool );
02074
02078 bool getDetectPending( void ) const
02079 { return detect_pending; }
02080
02085 void setDetectOutput( bool );
02086
02090 bool getDetectOutput( void ) const
02091 { return detect_output; }
02092
02097 virtual void expired(void)
02098 {return;};
02099
02104 virtual void pending(void)
02105 {return;};
02106
02111 virtual void output(void)
02112 {return;};
02113
02118 virtual void disconnect(void)
02119 {return;};
02120
02131 Error connect(const InetAddress &ia, tpport_t port);
02132
02142 inline int send(const void *buf, int len)
02143 {return ::send(so, (const char *)buf, len, 0);};
02144
02153 inline int receive(void *buf, size_t len)
02154 {return ::recv(so, (char *)buf, len, 0);};
02155
02164 inline int peek(void *buf, size_t len)
02165 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
02166
02167 public:
02175 void setTimer(timeout_t timeout = 0);
02176
02184 void incTimer(timeout_t timeout);
02185 };
02186
02199 class __EXPORT SocketService : public Thread, private Mutex
02200 {
02201 private:
02202 #ifndef WIN32
02203 fd_set connect;
02204 int iosync[2];
02205 int hiwater;
02206 #else
02207
02208 class Sync;
02209 Sync* sync;
02210 #endif
02211 int count;
02212 SocketPort *first, *last;
02213
02219 void attach(SocketPort *port);
02225 void detach(SocketPort *port);
02226
02230 void run(void);
02231
02232 friend class SocketPort;
02233
02234 protected:
02240 virtual void onUpdate(unsigned char buf)
02241 {return;};
02242
02248 virtual void onEvent(void)
02249 {return;};
02250
02258 virtual void onCallback(SocketPort *port)
02259 {return;};
02260
02261 public:
02272 void update(unsigned char flag = 0xff);
02273
02280 SocketService(int pri = 0, size_t stack = 0, const char *id = NULL);
02281
02286 virtual ~SocketService();
02287
02294 inline int getCount(void) const
02295 {return count;};
02296 };
02297
02298 #ifdef COMMON_STD_EXCEPTION
02299 class __EXPORT SockException : public IOException
02300 {
02301 private:
02302 Socket::Error _socketError;
02303
02304 public:
02305 SockException(String str, Socket::Error socketError, long systemError = 0) :
02306 IOException(str, systemError), _socketError(socketError) {};
02307
02308 inline Socket::Error getSocketError() const
02309 { return _socketError; }
02310 };
02311 #endif
02312
02313 #ifdef CCXX_NAMESPACES
02314 };
02315 #endif
02316
02317 #endif
02318