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_ADDRESS_H_
00050 #include <cc++/address.h>
00051 #endif
00052
00053 #if defined(WIN32) && !defined(__CYGWIN32__)
00054 #include <io.h>
00055 #define IOLEN (unsigned)
00056 #define IORET (ssize_t)
00057 #define TIMEOUT_INF ~((timeout_t) 0)
00058 typedef int socklen_t;
00059 #else
00060 #define INVALID_SOCKET -1
00061 typedef int SOCKET;
00062 #endif
00063
00064 #ifndef IOLEN
00065 #define IOLEN
00066 #endif
00067
00068 #ifndef IORET
00069 #define IORET
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
00083 typedef unsigned short tpport_t;
00084
00085 class __EXPORT SocketPort;
00086 class __EXPORT SocketService;
00087
00105 class __EXPORT Socket
00106 {
00107 public:
00108 enum Family
00109 {
00110 #ifdef CCXX_IPV6
00111 IPV6 = AF_INET6,
00112 #endif
00113 IPV4 = AF_INET
00114 };
00115
00116 typedef enum Family Family;
00117
00118 enum Error
00119 {
00120 errSuccess = 0,
00121 errCreateFailed,
00122 errCopyFailed,
00123 errInput,
00124 errInputInterrupt,
00125 errResourceFailure,
00126 errOutput,
00127 errOutputInterrupt,
00128 errNotConnected,
00129 errConnectRefused,
00130 errConnectRejected,
00131 errConnectTimeout,
00132 errConnectFailed,
00133 errConnectInvalid,
00134 errConnectBusy,
00135 errConnectNoRoute,
00136 errBindingFailed,
00137 errBroadcastDenied,
00138 errRoutingDenied,
00139 errKeepaliveDenied,
00140 errServiceDenied,
00141 errServiceUnavailable,
00142 errMulticastDisabled,
00143 errTimeout,
00144 errNoDelay,
00145 errExtended,
00146 errLookupFail,
00147 errSearchErr
00148 };
00149
00150 typedef enum Error Error;
00151
00152 enum Tos
00153 {
00154 tosLowDelay = 0,
00155 tosThroughput,
00156 tosReliability,
00157 tosMinCost,
00158 tosInvalid
00159 };
00160 typedef enum Tos Tos;
00161
00162 enum Pending
00163 {
00164 pendingInput,
00165 pendingOutput,
00166 pendingError
00167 };
00168 typedef enum Pending Pending;
00169
00170 protected:
00171 enum State
00172 {
00173 INITIAL,
00174 AVAILABLE,
00175 BOUND,
00176 CONNECTED,
00177 CONNECTING,
00178 STREAM
00179 };
00180 typedef enum State State;
00181
00182 private:
00183
00184 mutable Error errid;
00185 mutable const char *errstr;
00186 mutable long syserr;
00187
00188 void setSocket(void);
00189 friend SOCKET dupSocket(SOCKET s,Socket::State state);
00190
00191 protected:
00192 mutable struct
00193 {
00194 bool thrown: 1;
00195 bool broadcast: 1;
00196 bool route: 1;
00197 bool keepalive: 1;
00198 bool loopback: 1;
00199 bool multicast: 1;
00200 bool completion: 1;
00201 bool linger: 1;
00202 unsigned ttl: 8;
00203 } flags;
00204
00210 SOCKET volatile so;
00211 State volatile state;
00212
00221 Error error(Error error, char *err = NULL, long systemError = 0) const;
00222
00229 inline void error(char *err) const
00230 {error(errExtended, err);};
00231
00238 inline void setError(bool enable)
00239 {flags.thrown = !enable;};
00240
00246 void endSocket(void);
00247
00253 Error connectError(void);
00254
00263 Error setBroadcast(bool enable);
00264
00275 Error setMulticastByFamily(bool enable, Family family = IPV4);
00276
00284 Error setLoopbackByFamily(bool enable, Family family = IPV4);
00285
00292 Error setTimeToLiveByFamily(unsigned char ttl, Family fam = IPV4);
00293
00300 Error join(const IPV4Multicast &ia);
00301 #ifdef CCXX_IPV6
00302 Error join(const IPV6Multicast &ia);
00303 #endif
00304
00311 Error drop(const IPV4Multicast &ia);
00312 #ifdef CCXX_IPV6
00313 Error drop(const IPV6Multicast &ia);
00314 #endif
00315
00323 Error setRouting(bool enable);
00324
00325
00332 Error setNoDelay(bool enable);
00333
00345 Socket(int domain, int type, int protocol = 0);
00346
00354 Socket(SOCKET fd);
00355
00363 Socket(const Socket &source);
00364
00374 ssize_t readLine(char *buf, size_t len, timeout_t timeout = 0);
00375
00387 virtual ssize_t readData(void * buf,size_t len,char separator=0,timeout_t t=0);
00388
00397 virtual ssize_t writeData(const void* buf,size_t len,timeout_t t=0);
00398
00399
00400 public:
00408 virtual ~Socket();
00409
00413 Socket &operator=(const Socket &from);
00414
00424 IPV4Host getIPV4Sender(tpport_t *port = NULL) const;
00425
00426 inline IPV4Host getSender(tpport_t *port = NULL) const
00427 {return getIPV4Sender(port);}
00428
00429 #ifdef CCXX_IPV6
00430 IPV6Host getIPV6Sender(tpport_t *port = NULL) const;
00431 #endif
00432
00442 IPV4Host getIPV4Peer(tpport_t *port = NULL) const;
00443
00444 inline IPV4Host getPeer(tpport_t *port) const
00445 {return getIPV4Peer(port);}
00446
00447 #ifdef CCXX_IPV6
00448 IPV6Host getIPV6Peer(tpport_t *port = NULL) const;
00449 #endif
00450
00458 IPV4Host getIPV4Local(tpport_t *port = NULL) const;
00459
00460 inline IPV4Host getLocal(tpport_t *port) const
00461 {return getIPV4Local(port);}
00462
00463 #ifdef CCXX_IPV6
00464 IPV6Host getIPV6Local(tpport_t *port = NULL) const;
00465 #endif
00466
00494 IPV4Host getIPV4NAT(tpport_t *port = NULL) const;
00495
00496 inline IPV4Host getNAT(tpport_t *port) const
00497 {return getIPV4NAT(port);}
00498
00499 #ifdef CCXX_IPV6
00500 IPV6Host getIPV6NAT(tpport_t *port = NULL) const;
00501 #endif
00502
00513 void setCompletion(bool immediate);
00514
00520 Error setLinger(bool linger);
00521
00529 Error setKeepAlive(bool enable);
00530
00539 Error setTypeOfService(Tos service);
00540
00549 bool isConnected(void) const;
00550
00558 bool isActive(void) const;
00559
00564 bool operator!() const;
00565
00572 inline bool isBroadcast(void) const
00573 {return flags.broadcast;};
00574
00580 inline bool isRouted(void) const
00581 {return flags.route;};
00582
00589 inline Error getErrorNumber(void) const {return errid;}
00590
00597 inline const char *getErrorString(void) const {return errstr;}
00598
00599 inline long getSystemError(void) const {return syserr;}
00600
00601 const char *getSystemErrorString(void) const;
00602
00612 virtual bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
00613 };
00614
00647 class __EXPORT UDPSocket : public Socket
00648 {
00649 private:
00650 inline Error setKeepAlive(bool enable)
00651 {return Socket::setKeepAlive(enable);};
00652
00653 protected:
00654 #ifdef CCXX_IPV6
00655 union
00656 {
00657 struct sockaddr_in6 ipv6;
00658 struct sockaddr_in ipv4;
00659 } peer;
00660 #else
00661 union
00662 {
00663 struct sockaddr_in ipv4;
00664 } peer;
00665 #endif
00666
00667 Family family;
00668
00669 public:
00673 UDPSocket(Family family = IPV4);
00674
00684 UDPSocket(const IPV4Address &bind, tpport_t port);
00685 #ifdef CCXX_IPV6
00686 UDPSocket(const IPV6Address &bind, tpport_t port);
00687 #endif
00688
00692 virtual ~UDPSocket();
00693
00697 inline Error setLoopback(bool enable)
00698 {return Socket::setLoopbackByFamily(enable, family);}
00699
00703 inline Error setMulticast(bool enable)
00704 {return Socket::setMulticastByFamily(enable, family);}
00705
00709 inline Error setTimeToLive(char ttl)
00710 {return Socket::setTimeToLiveByFamily(ttl, family);}
00711
00719 void setPeer(const IPV4Host &host, tpport_t port);
00720 #ifdef CCXX_IPV6
00721 void setPeer(const IPV6Host &host, tpport_t port);
00722 #endif
00723
00731 Socket::Error getInterfaceIndex(const char *ethX,int& InterfaceIndex);
00732
00741 Socket::Error join(const IPV4Multicast &ia,int InterfaceIndex);
00742
00743
00751 inline ssize_t send(const void *buf, size_t len)
00752 {return IORET ::sendto(so, (const char*)buf, IOLEN len, 0, (struct sockaddr *)&peer, (socklen_t)sizeof(peer));};
00753
00761 inline ssize_t receive(void *buf, size_t len)
00762 {return IORET ::recv(so, (char *)buf, IOLEN len, 0);};
00763
00772 IPV4Host getIPV4Peer(tpport_t *port = NULL) const;
00773 inline IPV4Host getPeer(tpport_t *port = NULL) const
00774 {return getIPV4Peer(port);}
00775
00776 #ifdef CCXX_IPV6
00777 IPV6Host getIPV6Peer(tpport_t *port = NULL) const;
00778 #endif
00779
00787 inline ssize_t peek(void *buf, size_t len)
00788 {return IORET ::recv(so, (char *)buf, IOLEN len, MSG_PEEK);};
00789
00794 Error disconnect(void);
00795 };
00796
00797
00806 class __EXPORT UDPBroadcast : public UDPSocket
00807 {
00808 private:
00809 void setPeer(const IPV4Host &ia, tpport_t port) {};
00810
00811 Error setBroadcast(bool enable)
00812 {return Socket::setBroadcast(enable);};
00813
00814 public:
00821 UDPBroadcast(const IPV4Address &ia, tpport_t port);
00822
00829 void setPeer(const IPV4Broadcast &subnet, tpport_t port);
00830 };
00831
00840 class __EXPORT UDPTransmit : protected UDPSocket
00841 {
00842 private:
00850 Error cConnect(const IPV4Address &ia, tpport_t port);
00851
00852 protected:
00856 UDPTransmit(Family family = IPV4);
00857
00869 UDPTransmit(const IPV4Address &bind, tpport_t port = 5005);
00870 #ifdef CCXX_IPV6
00871 UDPTransmit(const IPV6Address &bind, tpport_t port = 5005);
00872 #endif
00873
00883 Error connect(const IPV4Host &host, tpport_t port);
00884 #ifdef CCXX_IPV6
00885 Error connect(const IPV6Address &host, tpport_t port);
00886 #endif
00887
00897 Error connect(const IPV4Broadcast &subnet, tpport_t port);
00898
00906 Error connect(const IPV4Multicast &mgroup, tpport_t port);
00907 #ifdef CCXX_IPV6
00908 Error connect(const IPV6Multicast &mgroup, tpport_t port);
00909 #endif
00910
00918 inline ssize_t send(const void *buf, size_t len)
00919 {return IORET ::send(so, (const char *)buf, IOLEN len, 0);}
00920
00924 inline void endTransmitter(void)
00925 {Socket::endSocket();}
00926
00927
00928
00929
00930
00931
00932 inline SOCKET getTransmitter(void)
00933 {return so;};
00934
00935 inline Error setMulticast(bool enable)
00936 {return Socket::setMulticastByFamily(enable, family);}
00937
00938 inline Error setTimeToLive(unsigned char ttl)
00939 {return Socket::setTimeToLiveByFamily(ttl, family);};
00940
00941 public:
00951 inline ssize_t transmit(const char *buffer, size_t len)
00952 {return IORET ::send(so, buffer, IOLEN len, MSG_DONTWAIT);}
00953
00960 inline bool isOutputReady(unsigned long timeout = 0l)
00961 {return Socket::isPending(Socket::pendingOutput, timeout);};
00962
00963
00964 inline Error setRouting(bool enable)
00965 {return Socket::setRouting(enable);};
00966
00967 inline Error setTypeOfService(Tos tos)
00968 {return Socket::setTypeOfService(tos);};
00969
00970 inline Error setBroadcast(bool enable)
00971 {return Socket::setBroadcast(enable);};
00972 };
00973
00982 class __EXPORT UDPReceive : protected UDPSocket
00983 {
00984 protected:
00995 UDPReceive(const IPV4Address &bind, tpport_t port);
00996 #ifdef CCXX_IPV6
00997 UDPReceive(const IPV6Address &bind, tpport_t port);
00998 #endif
00999
01009 Error connect(const IPV4Host &host, tpport_t port);
01010 #ifdef CCXX_IPV6
01011 Error connect(const IPV6Host &host, tpport_t port);
01012 #endif
01013
01020 bool isPendingReceive(timeout_t timeout)
01021 {return Socket::isPending(Socket::pendingInput, timeout);};
01022
01026 inline void endReceiver(void)
01027 {Socket::endSocket();}
01028
01029 inline SOCKET getReceiver(void) const
01030 {return so;};
01031
01032 inline Error setRouting(bool enable)
01033 {return Socket::setRouting(enable);}
01034
01035 inline Error setMulticast(bool enable)
01036 {return Socket::setMulticastByFamily(enable, family);}
01037
01038 inline Error join(const IPV4Multicast &ia)
01039 {return Socket::join(ia);}
01040
01041 #ifdef CCXX_IPV6
01042 inline Error join(const IPV6Multicast &ia)
01043 {return Socket::join(ia);}
01044 #endif
01045
01046 inline Error drop(const IPV4Multicast &ia)
01047 {return Socket::drop(ia);}
01048
01049 #ifdef CCXX_IPV6
01050 inline Error drop(const IPV6Multicast &ia)
01051 {return Socket::drop(ia);}
01052 #endif
01053
01054 public:
01062 inline ssize_t receive(void *buf, size_t len)
01063 {return IORET ::recv(so, (char *)buf, IOLEN len, 0);};
01064
01071 inline bool isInputReady(timeout_t timeout = TIMEOUT_INF)
01072 {return Socket::isPending(Socket::pendingInput, timeout);};
01073 };
01074
01085 class __EXPORT UDPDuplex : public UDPTransmit, public UDPReceive
01086 {
01087 public:
01095 UDPDuplex(const IPV4Address &bind, tpport_t port);
01096 #ifdef CCXX_IPV6
01097 UDPDuplex(const IPV6Address &bind, tpport_t port);
01098 #endif
01099
01109 Error connect(const IPV4Host &host, tpport_t port);
01110 #ifdef CCXX_IPV6
01111 Error connect(const IPV6Host &host, tpport_t port);
01112 #endif
01113
01120 Error disconnect(void);
01121 };
01122
01123
01148 class __EXPORT TCPSocket : protected Socket
01149 {
01150 protected:
01162 virtual bool onAccept(const IPV4Host &ia, tpport_t port)
01163 {return true;}
01164
01165 friend class TCPStream;
01166 friend class SocketPort;
01167 friend class tcpstream;
01168 friend class SimpleTCPStream;
01169
01170 public:
01182 TCPSocket(const IPV4Address &bind, tpport_t port, int backlog = 5);
01183
01192 inline IPV4Host getRequest(tpport_t *port = NULL) const
01193 {return Socket::getIPV4Sender(port);}
01194
01198 void reject(void);
01199
01203 inline IPV4Host getLocal(tpport_t *port = NULL) const
01204 {return Socket::getIPV4Local(port);}
01205
01211 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF)
01212 {return Socket::isPending(Socket::pendingInput, timeout);}
01213
01217 virtual ~TCPSocket()
01218 {endSocket();};
01219 };
01220
01221 #ifdef CCXX_IPV6
01222
01246 class __EXPORT TCPV6Socket : protected Socket
01247 {
01248 protected:
01260 virtual bool onAccept(const IPV6Host &ia, tpport_t port)
01261 {return true;}
01262
01263 friend class TCPStream;
01264 friend class SocketPort;
01265 friend class tcpstream;
01266 friend class SimpleTCPStream;
01267
01268 public:
01280 TCPV6Socket(const IPV6Address &bind, tpport_t port, int backlog = 5);
01281
01290 inline IPV6Host getRequest(tpport_t *port = NULL) const
01291 {return Socket::getIPV6Sender(port);}
01292
01296 void reject(void);
01297
01301 inline IPV6Host getLocal(tpport_t *port = NULL) const
01302 {return Socket::getIPV6Local(port);}
01303
01309 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF)
01310 {return Socket::isPending(Socket::pendingInput, timeout);}
01311
01315 virtual ~TCPV6Socket()
01316 {endSocket();};
01317 };
01318
01319 #endif
01320
01321
01322
01323
01324
01325
01326
01327
01328 #ifdef _MSC_VER
01329 #pragma warning(disable:4275) // disable C4275 warning
01330 #endif
01331
01345 class __EXPORT TCPStream : protected std::streambuf, public Socket, public std::iostream
01346 {
01347 private:
01348 inline Error setBroadcast(bool enable)
01349 {return Socket::setBroadcast(enable);};
01350
01351 inline IPV4Host getSender(tpport_t *port) const
01352 {return IPV4Host();}
01353
01354 inline IPV4Host getIPV4Sender(tpport_t *port) const
01355 {return IPV4Host();}
01356
01357 #ifdef CCXX_IPV6
01358 inline IPV6Host getIPV6Sender(tpport_t *port) const
01359 {return IPV6Host();}
01360 #endif
01361
01362 int doallocate();
01363
01364 friend TCPStream& crlf(TCPStream&);
01365 friend TCPStream& lfcr(TCPStream&);
01366
01367 protected:
01368 timeout_t timeout;
01369 int bufsize;
01370 Family family;
01371 char *gbuf, *pbuf;
01372
01377 TCPStream(Family family = IPV4, bool throwflag = true);
01378
01385 void allocate(int size);
01386
01391 void endStream(void);
01392
01399 int underflow();
01400
01409 int uflow();
01410
01418 int overflow(int ch);
01419
01428 void connect(const IPV4Host &host, tpport_t port, int size);
01429 #ifdef CCXX_IPV6
01430 void connect(const IPV6Host &host, tpport_t port, int size);
01431 #endif
01432
01440 std::iostream *tcp(void)
01441 {return ((std::iostream *)this);};
01442
01443 public:
01454 TCPStream(TCPSocket &server, int size = 512, bool throwflag = true, timeout_t timeout = 0);
01455 #ifdef CCXX_IPV6
01456 TCPStream(TCPV6Socket &server, int size = 512, bool throwflag = true, timeout_t timeout = 0);
01457 #endif
01458
01469 TCPStream(const IPV4Host &host, tpport_t port, int size = 512, bool throwflag = true, timeout_t timeout = 0);
01470 #ifdef CCXX_IPV6
01471 TCPStream(const IPV6Host &host, tpport_t port, int size = 512, bool throwflag = true, timeout_t timeout = 0);
01472 #endif
01473
01479 inline void setTimeout(timeout_t to)
01480 {timeout = to;};
01481
01488 TCPStream(const TCPStream &source);
01489
01494 virtual ~TCPStream()
01495 {
01496 #ifdef CCXX_EXCEPTIONS
01497 try { endStream(); }
01498 catch( ... ) { if ( ! std::uncaught_exception()) throw; }
01499 #else
01500 endStream();
01501 #endif
01502 };
01503
01510 int sync(void);
01511
01512 #ifdef HAVE_SNPRINTF
01513
01519 int printf(const char *format, ...);
01520 #endif
01521
01529 bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
01530
01538 inline ssize_t peek(void *buf, size_t len)
01539 {return IORET ::recv(so, (char *)buf, IOLEN len, MSG_PEEK);};
01540
01546 int getBufferSize(void) const
01547 {return bufsize;};
01548 };
01549
01558 class __EXPORT tcpstream : public TCPStream
01559 {
01560 public:
01561
01562 tcpstream(const tcpstream &rhs):TCPStream(rhs) {};
01563
01567 tcpstream();
01568
01576 tcpstream(const char *addr, int buffer = 512);
01577
01585 tcpstream(TCPSocket &tcp, int buffer = 512);
01586
01594 void open(const char *addr, int buffer = 512);
01595
01602 void open(TCPSocket &tcp, int buffer = 512);
01603
01607 void close(void);
01608
01612 bool operator!() const;
01613 };
01614
01625 class __EXPORT TCPSession : public TCPStream, public Thread
01626 {
01627 private:
01628 TCPSession(const TCPSession &rhs);
01629 protected:
01642 int waitConnection(timeout_t timeout = TIMEOUT_INF);
01643
01650 void initial(void);
01651
01662 void final(void)
01663 {delete this;};
01664 public:
01675 TCPSession(const IPV4Host &host,
01676 tpport_t port, int size = 512, int pri = 0, int stack = 0);
01677 #ifdef CCXX_IPV6
01678 TCPSession(const IPV6Host &host,
01679 tpport_t port, int size = 512, int pri = 0, int stack = 0);
01680 #endif
01681
01692 TCPSession(TCPSocket &server, int size = 512,
01693 int pri = 0, int stack = 0);
01694 #ifdef CCXX_IPV6
01695 TCPSession(TCPV6Socket &server, int size = 512,
01696 int pri = 0, int stack = 0);
01697 #endif
01698 };
01699
01700 #if defined(WIN32)
01701
01711 class init_WSA
01712 {
01713 public:
01714 init_WSA();
01715 ~init_WSA();
01716 };
01717
01718 #endif // WIN32
01719
01720 class __EXPORT SimpleTCPStream;
01721
01733 class __EXPORT SimpleTCPStream : protected Socket
01734 {
01735 private:
01736
01737 inline IPV4Host getSender(tpport_t *port) const
01738 { return IPV4Host(); };
01739
01740 protected:
01745 SimpleTCPStream();
01746
01751 void endStream(void);
01752
01761 void Connect(const IPV4Host &host, tpport_t port, int size);
01762
01763
01764 public:
01773 SimpleTCPStream(TCPSocket &server, int size = 512);
01774
01783 SimpleTCPStream(const IPV4Host &host, tpport_t port, int size = 512);
01784
01790 SimpleTCPStream(const SimpleTCPStream &source);
01791
01796 virtual ~SimpleTCPStream() { endStream(); };
01797
01809 bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
01810
01811 void flush() {}
01812
01824 ssize_t read(char *bytes, size_t length, timeout_t timeout = 0);
01825
01837 ssize_t write(const char *bytes, size_t length, timeout_t timeout = 0);
01838
01852 ssize_t peek(char *bytes, size_t length, timeout_t timeout = 0);
01853
01854 };
01855
01856 class __EXPORT SocketService;
01857
01877 class __EXPORT SocketPort : public Socket, public TimerPort
01878 {
01879 private:
01880 SocketPort *next, *prev;
01881 SocketService *service;
01882 #ifndef WIN32
01883 struct timeval porttimer;
01884 #ifdef USE_POLL
01885 struct pollfd * ufd;
01886 #endif
01887 #else
01888 HANDLE event;
01889 #endif
01890 bool detect_pending;
01891 bool detect_output;
01892 bool detect_disconnect;
01893
01894 friend class SocketService;
01895
01896 protected:
01905 SocketPort(SocketService *svc, TCPSocket &tcp);
01906 #ifdef CCXX_IPV6
01907 SocketPort(SocketService *svc, TCPV6Socket &tcp);
01908 #endif
01909
01918 SocketPort(SocketService *svc, const IPV4Address &ia, tpport_t port);
01919 #ifdef CCXX_IPV6
01920 SocketPort(SocketService *svc, const IPV6Address &ia, tpport_t port);
01921 #endif
01922
01936 SocketPort(SocketService *svc, const IPV4Host &ih, tpport_t port);
01937 #ifdef CCXX_IPV6
01938 SocketPort(SocketService *svc, const IPV6Host &ih, tpport_t port);
01939 #endif
01940
01946 void attach( SocketService* svc );
01947
01948
01953 virtual ~SocketPort();
01954
01959 void setDetectPending( bool );
01960
01964 bool getDetectPending( void ) const
01965 { return detect_pending; }
01966
01971 void setDetectOutput( bool );
01972
01976 bool getDetectOutput( void ) const
01977 { return detect_output; }
01978
01983 virtual void expired(void)
01984 {return;};
01985
01990 virtual void pending(void)
01991 {return;};
01992
01997 virtual void output(void)
01998 {return;};
01999
02004 virtual void disconnect(void)
02005 {return;};
02006
02017 Error connect(const IPV4Address &ia, tpport_t port);
02018 #ifdef CCXX_IPV6
02019 Error connect(const IPV6Address &ia, tpport_t port);
02020 #endif
02021
02031 inline ssize_t send(const void *buf, size_t len)
02032 {return IORET ::send(so, (const char *)buf, IOLEN len, 0);};
02033
02042 inline ssize_t receive(void *buf, size_t len)
02043 {return IORET ::recv(so, (char *)buf, IOLEN len, 0);};
02044
02053 inline ssize_t peek(void *buf, size_t len)
02054 {return IORET ::recv(so, (char *)buf, IOLEN len, MSG_PEEK);};
02055
02056 public:
02064 void setTimer(timeout_t timeout = 0);
02065
02073 void incTimer(timeout_t timeout);
02074 };
02075
02088 class __EXPORT SocketService : public Thread, private Mutex
02089 {
02090 private:
02091 #ifndef WIN32
02092 fd_set connect;
02093 int iosync[2];
02094 int hiwater;
02095 #else
02096
02097 class Sync;
02098 Sync* sync;
02099 #endif
02100 int volatile count;
02101 SocketPort* volatile first, *last;
02102
02108 void attach(SocketPort *port);
02114 void detach(SocketPort *port);
02115
02119 void run(void);
02120
02121 friend class SocketPort;
02122
02123 protected:
02129 virtual void onUpdate(unsigned char buf)
02130 {return;};
02131
02137 virtual void onEvent(void)
02138 {return;};
02139
02147 virtual void onCallback(SocketPort *port)
02148 {return;};
02149
02150 public:
02161 void update(unsigned char flag = 0xff);
02162
02171 SocketService(int pri = 0, size_t stack = 0, const char *id = NULL);
02172
02177 virtual ~SocketService();
02178
02185 inline int getCount(void) const
02186 {return count;};
02187 };
02188
02189 #ifdef COMMON_STD_EXCEPTION
02190 class __EXPORT SockException : public IOException
02191 {
02192 private:
02193 Socket::Error _socketError;
02194
02195 public:
02196 SockException(const String &str, Socket::Error socketError, long systemError = 0) :
02197 IOException(str, systemError), _socketError(socketError) {};
02198
02199 inline Socket::Error getSocketError() const
02200 { return _socketError; }
02201 };
02202 #endif
02203
02204 #ifdef CCXX_NAMESPACES
02205 }
02206 #endif
02207
02208 #endif
02209