Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages | Examples

socket.h

Go to the documentation of this file.
00001 // Copyright (C) 1999-2003 Open Source Telecom Corporation.
00002 //
00003 // This program is free software; you can redistribute it and/or modify
00004 // it under the terms of the GNU General Public License as published by
00005 // the Free Software Foundation; either version 2 of the License, or
00006 // (at your option) any later version.
00007 //
00008 // This program is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 // GNU General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this program; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00016 //
00017 // As a special exception to the GNU General Public License, permission is
00018 // granted for additional uses of the text contained in its release
00019 // of Common C++.
00020 //
00021 // The exception is that, if you link the Common C++ library with other files
00022 // to produce an executable, this does not by itself cause the
00023 // resulting executable to be covered by the GNU General Public License.
00024 // Your use of that executable is in no way restricted on account of
00025 // linking the Common C++ library code into it.
00026 //
00027 // This exception does not however invalidate any other reasons why
00028 // the executable file might be covered by the GNU General Public License.
00029 //
00030 // This exception applies only to the code released under the
00031 // name Common C++.  If you copy code from other releases into a copy of
00032 // Common C++, as the General Public License permits, the exception does
00033 // not apply to the code that you add in this way.  To avoid misleading
00034 // anyone as to the status of such modified files, you must delete
00035 // this exception notice from them.
00036 //
00037 // If you write modifications of your own for Common C++, it is your choice
00038 // whether to permit this exception to apply to your modifications.
00039 // If you do not wish that, delete this exception notice.
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         // The validator given to an InetAddress object must not be a
00169         // transient object, but that must exist at least until the
00170         // last address object of its kind is deleted. This is an
00171         // artifact to be able to do specific checks for derived
00172         // classes inside constructors.
00173         const InetAddrValidator *validator;
00174 
00175 protected:
00176         struct in_addr * ipaddr;
00177         size_t addr_count;
00178         mutable char* hostname;  // hostname for ipaddr[0]. Used by getHostname
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         // used by exception handlers....
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          * Get transmitter socket.
01199          *
01200          * @return transmitter.
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; // Added by Mark S. Millard
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) /* not const -- jfc */
01460                 {return Socket::isPending(Socket::pendingInput, timeout);}
01461 
01465         virtual ~TCPSocket()
01466                 {endSocket();};
01467 };
01468 
01469 /*
01470 :\projects\libraries\cplusplus\commonc++\win32\socket.h(357) : warning C4275: non dll-interface class 'streambuf' used as base for dll-interface class 'TCPStream'
01471         c:\program files\microsoft visual studio\vc98\include\streamb.h(69) : see declaration of 'streambuf'
01472 c:\projects\libraries\cplusplus\commonc++\win32\socket.h(358) : warning C4275: non dll-interface class 'iostream' used as base for dll-interface class 'TCPStream'
01473         c:\program files\microsoft visual studio\vc98\include\iostream.h(66) : see declaration of 'iostream'
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         // copy constructor (fix a BUG in msvc7 compiler)
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); // not defined
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         // private syncronization class
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 

Generated on Fri Feb 27 11:37:10 2004 for GNU CommonC++ by doxygen 1.3.5