Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

socket.h

Go to the documentation of this file.
00001 // Copyright (C) 1999-2000 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 
00041 #ifndef __CCXX_SOCKET_H__
00042 #define __CCXX_SOCKET_H__
00043 
00044 #ifndef __CCXX_THREAD_H__
00045 #include <cc++/thread.h>
00046 #else
00047 #ifdef  __CCXX_NAMESPACE_H__
00048 #include <cc++/macros.h>
00049 #endif
00050 #endif
00051 
00052 #include <iostream.h>
00053 
00054 typedef enum
00055 {
00056         SOCKET_COMPLETION_IMMEDIATE,
00057         SOCKET_COMPLETION_DELAYED
00058 } sockcomplete_t;
00059 
00060 typedef enum
00061 {
00062         SOCKET_INITIAL,
00063         SOCKET_AVAILABLE,
00064         SOCKET_BOUND,
00065         SOCKET_CONNECTED,
00066         SOCKET_CONNECTING
00067 } sockstate_t;
00068 
00069 typedef enum
00070 {
00071         SOCKET_SUCCESS=0,
00072         SOCKET_CREATE_FAILED,
00073         SOCKET_COPY_FAILED,
00074         SOCKET_INPUT_ERROR,
00075         SOCKET_INPUT_INTERRUPT,
00076         SOCKET_RESOURCE_FAILURE,
00077         SOCKET_OUTPUT_ERROR,
00078         SOCKET_OUTPUT_INTERRUPT,
00079         SOCKET_NOT_CONNECTED,
00080         SOCKET_CONNECT_REFUSED,
00081         SOCKET_CONNECT_REJECTED,
00082         SOCKET_CONNECT_TIMEOUT,
00083         SOCKET_CONNECT_FAILED,
00084         SOCKET_CONNECT_INVALID,
00085         SOCKET_CONNECT_BUSY,
00086         SOCKET_CONNECT_NOROUTE,
00087         SOCKET_BINDING_FAILED,
00088         SOCKET_BROADCAST_DENIED,
00089         SOCKET_ROUTING_DENIED,
00090         SOCKET_KEEPALIVE_DENIED,
00091         SOCKET_SERVICE_DENIED,
00092         SOCKET_SERVICE_UNAVAILABLE,
00093         SOCKET_EXTENDED_ERROR
00094 } sockerror_t;
00095 
00096 typedef enum
00097 {
00098         SOCKET_IPTOS_LOWDELAY,
00099         SOCKET_IPTOS_THROUGHPUT,
00100         SOCKET_IPTOS_RELIABILITY,
00101         SOCKET_IPTOS_MINCOST,
00102         SOCKET_IPTOS_INVALID
00103 } socktos_t;
00104 
00105 typedef enum
00106 {
00107         SOCKET_PENDING_INPUT,
00108         SOCKET_PENDING_OUTPUT,
00109         SOCKET_PENDING_ERROR
00110 } sockpend_t;
00111 
00115 typedef unsigned short tpport_t;
00116 
00117 class InetHostAddress;
00118 class InetMaskAddress;
00119 
00134 class InetAddress 
00135 {
00136 protected:
00137         struct in_addr ipaddr;
00138         static Mutex mutex;
00139 
00145         void setAddress(const char *address);
00146 
00147 public:
00152         InetAddress();
00153 
00161         InetAddress(struct in_addr);
00162 
00169         InetAddress(const char *address);
00170 
00177         const char *getHostname(void) const;
00178 
00186         bool isInetAddress(void) const;
00187 
00195         inline struct in_addr getAddress(void) const
00196                 {return ipaddr;};
00197 
00198         InetAddress &operator=(const char *str);
00199         InetAddress &operator=(struct in_addr addr);
00200 
00201         inline bool operator!() const
00202                 {return !isInetAddress();};
00203 
00208         bool operator==(const InetAddress &a) const;
00209 
00215         bool operator!=(const InetAddress &a) const;
00216 };      
00217 
00230 class InetMaskAddress : public InetAddress
00231 {
00232 public:
00239         InetMaskAddress(const char *mask);
00240 
00251         friend InetHostAddress operator&(const InetHostAddress &addr, 
00252                                          const InetMaskAddress &mask);
00253 };
00254 
00262 class InetHostAddress : public InetAddress
00263 {
00264 public:
00270         InetHostAddress();
00271  
00281         InetHostAddress(const char *host);
00282 
00290         InetHostAddress(struct in_addr addr);
00291 
00292 
00297         InetHostAddress &operator&=(const InetMaskAddress &mask);
00298 
00299         friend class InetMaskAddress;
00300         friend InetHostAddress operator&(const InetHostAddress &addr, 
00301                                          const InetMaskAddress &mask);
00302 };
00303 
00308 class BroadcastAddress : public InetAddress
00309 {
00310 public:
00318         BroadcastAddress(const char *net = "255.255.255.255");
00319 };
00320 
00338 class Socket
00339 {
00340 private:
00341         // used to throw
00342         mutable sockerror_t errid;
00343         mutable const char *errstr;
00344 
00345         mutable struct
00346         {
00347                 bool thrown: 1;
00348                 bool broadcast: 1;
00349                 bool route: 1;
00350                 bool keepalive: 1;
00351         } flags;
00352 
00353         void setSocket(void);
00354 
00355 protected:
00356         sockstate_t state;
00357         int so;
00358 
00366         sockerror_t Error(sockerror_t error, char *errstr = NULL) const;
00367 
00374         inline void Error(char *estr)
00375                 {Error(SOCKET_EXTENDED_ERROR, estr);};
00376         
00383         inline void setError(bool enable)
00384                 {flags.thrown = !enable;};
00385 
00391         void endSocket(void);
00392 
00398         sockerror_t connectError(void);
00399 
00408         sockerror_t setBroadcast(bool enable);
00409 
00417         sockerror_t setRouting(bool enable);
00418 
00430         Socket(int domain, int type, int protocol = 0);
00431 
00439         Socket(int fd);
00440 
00448         Socket(const Socket &source);
00449 
00450 public:
00458         virtual ~Socket()
00459                 {endSocket();};
00460 
00464         Socket &operator=(const Socket &from);
00465 
00475         InetHostAddress getSender(tpport_t *port = NULL) const;
00476 
00486         InetHostAddress getPeer(tpport_t *port = NULL) const;
00487 
00495         InetHostAddress getLocal(tpport_t *port = NULL) const;
00496         
00507         void setCompletion(sockcomplete_t completion);
00508 
00516         sockerror_t setKeepAlive(bool enable);
00517 
00526         sockerror_t setTypeOfService(socktos_t service);
00527 
00536         bool isConnected(void) const;
00537 
00545         bool isActive(void) const;
00546 
00551         bool operator!() const;
00552 
00559         inline bool isBroadcast(void) const
00560                 {return flags.broadcast;};
00561 
00567         inline bool isRouted(void) const
00568                 {return flags.route;};
00569 
00576         inline sockerror_t getErrorNumber(void) const
00577                 {return errid;};
00578         
00585         inline const char *getErrorString(void) const
00586                 {return errstr;};
00587 
00597         virtual bool isPending(sockpend_t pend, timeout_t timeout = TIMEOUT_INF);
00598 };
00599 
00632 class UDPSocket : public Socket
00633 {
00634 private:
00635         inline sockerror_t setKeepAlive(bool enable)
00636                 {return Socket::setKeepAlive(enable);};
00637 
00638 protected:
00639         struct sockaddr_in peer;
00640 
00641 public:
00645         UDPSocket(void);
00646 
00656         UDPSocket(const InetAddress &bind, tpport_t port);
00657 
00661         ~UDPSocket()
00662                 {endSocket();};
00663 
00671         void setPeer(const InetHostAddress &host, tpport_t port);
00672 
00680         inline int Send(void *buf, size_t len)
00681                 {return ::sendto(so, (char *)buf, len, 0, (struct sockaddr *)&peer, (socklen_t)sizeof(peer));};
00682 
00690         inline int Recv(void *buf, size_t len)
00691                 {return ::recv(so, (char *)buf, len, 0);};
00692 
00701         InetHostAddress getPeer(tpport_t *port = NULL);
00702 
00710         inline int Peek(void *buf, size_t len)
00711                 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
00712 };
00713 
00714 
00723 class UDPBroadcast : public UDPSocket
00724 {
00725 private:
00726         void setPeer(const InetHostAddress &ia, tpport_t port) {};
00727 
00728         sockerror_t setBroadcast(bool enable)
00729                 {return Socket::setBroadcast(enable);};
00730 
00731 public:
00738         UDPBroadcast(const InetAddress &ia, tpport_t port);
00739 
00746         void setPeer(const BroadcastAddress &ia, tpport_t port);
00747 };      
00748 
00757 class UDPTransmit : private UDPSocket
00758 {
00759 protected:
00763         UDPTransmit();
00764 
00777         UDPTransmit(const InetAddress &bind, tpport_t port = 5005);
00778 
00787         sockerror_t Connect(const InetHostAddress &host, tpport_t port);
00788 
00797         sockerror_t Connect(const BroadcastAddress &subnet, tpport_t port);
00798 
00803         sockerror_t Disconnect(void);
00804 
00812         inline int Send(void *buf, int len)
00813                 {return ::send(so, (char *)buf, len, 0);};
00814 
00818         inline void endTransmit(void)
00819                 {Socket::endSocket();};
00820 
00821         /*
00822          * Get transmitter socket.
00823          *
00824          * @return transmitter.
00825          */
00826         inline int getTransmitter(void)
00827                 {return so;};
00828 
00829 public:
00833         inline int Transmit(unsigned char *buffer, size_t len)
00834                 {return ::send(so, buffer, len, MSG_DONTWAIT);};
00835 
00836         inline sockerror_t setRouting(bool enable)
00837                 {return Socket::setRouting(enable);};
00838 
00839         inline sockerror_t setTypeOfService(socktos_t tos)
00840                 {return Socket::setTypeOfService(tos);};
00841 
00842         inline sockerror_t setBroadcast(bool enable)
00843                 {return Socket::setBroadcast(enable);};
00844 };
00845 
00854 class UDPReceive : private UDPSocket
00855 {
00856 protected:
00868         UDPReceive(const InetAddress &bind, tpport_t port);
00869 
00878         sockerror_t Connect(const InetHostAddress &host, tpport_t port);
00879 
00884         sockerror_t Disconnect(void);
00885 
00889         inline void endReceiver(void)
00890                 {Socket::endSocket();};
00891 
00892         inline int getReceiver(void)
00893                 {return so;};
00894 
00895 public:
00903         inline int Receive(void *buf, size_t len)
00904                 {return ::recv(so, (char *)buf, len, 0);};
00905 
00912         inline bool isInputReady(timeout_t timeout = TIMEOUT_INF)
00913                 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);};
00914 };
00915 
00926 class UDPDuplex : public UDPTransmit, public UDPReceive
00927 {
00928 public:
00937         UDPDuplex(const InetAddress &bind, tpport_t port);
00938 
00948         sockerror_t Connect(const InetHostAddress &host, tpport_t port);
00949 
00956         sockerror_t Disconnect(void);
00957 };
00958 
00959 
00985 class TCPSocket : private Socket
00986 {
00987 protected:
00995         virtual bool OnAccept(const InetHostAddress &ia, short port) {
00996                 return false;
00997         }
00998 
01010         virtual bool OnAccept(const InetHostAddress &ia, tpport_t port)
01011                 {return true;};
01012 
01013         friend class TCPStream;
01014         friend class SocketPort;
01015         friend class tcpstream;
01016 
01017 public:
01029         TCPSocket(const InetAddress &bind, tpport_t port, int backlog = 5);
01030         
01039         inline InetHostAddress getRequest(tpport_t *port = NULL) const
01040                 {return Socket::getSender(port);};
01041 
01045         void Reject(void);
01046 
01050         inline InetHostAddress getLocal(tpport_t *port = NULL) const
01051                 {return Socket::getLocal(port);};
01052 
01056         inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF)
01057                 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);};
01058 
01062         ~TCPSocket()
01063                 {endSocket();};
01064 };
01065 
01080 class TCPStream : public streambuf, public iostream, public Socket
01081 {
01082 private:
01083         inline sockerror_t setBroadcast(bool enable)
01084                 {return Socket::setBroadcast(enable);};
01085 
01086         inline InetHostAddress getSender(tpport_t *port) const
01087                 {return InetHostAddress();};
01088 
01089         int doallocate();
01090 
01091         friend TCPStream& crlf(TCPStream&);
01092         friend TCPStream& lfcr(TCPStream&);
01093 
01094 protected:
01095         int bufsize;
01096         char *gbuf, *pbuf;
01097 
01102         TCPStream();
01103 
01110         void Allocate(int size);
01111 
01116         void endStream(void);
01117 
01124         int underflow(void);
01125 
01134         int uflow(void);
01135 
01143         int overflow(int ch);
01144 
01152         iostream *tcp(void)
01153                 {return ((iostream *)this);};
01154 
01155 public:
01163         TCPStream(TCPSocket &server, int size = 512);
01164 
01173         TCPStream(const InetHostAddress &host, tpport_t port, int size = 512);
01174 
01181         TCPStream(const TCPStream &source);
01182 
01187         ~TCPStream()
01188                 {endStream();};
01189 
01196         int sync(void);
01197 
01205         bool isPending(sockpend_t pend, timeout_t timeout = TIMEOUT_INF);
01206 
01212         int getBufferSize(void) const
01213                 {return bufsize;};
01214 };
01215 
01224 class tcpstream : public TCPStream
01225 {
01226 public:
01230         tcpstream();
01231 
01239         tcpstream(const char *addr, int buffer = 512);
01240 
01248         tcpstream(TCPSocket &tcp, int buffer = 512);
01249 
01257         void open(const char *addr, int buffer = 512);
01258 
01265         void open(TCPSocket &tcp, int buffer = 512);
01266 
01270         void close(void);
01271 
01275         bool operator!() const;
01276 };              
01277 
01288 class TCPSession : public TCPStream, public Thread
01289 {
01290 protected:
01303         int WaitConnection(timeout_t timeout = TIMEOUT_INF);
01304 
01311         void Initial(void);
01312 
01318         void Final(void)
01319                 {delete this;};
01320 public:
01332         TCPSession(Semaphore *start, const InetHostAddress &host, 
01333                    tpport_t port, int size = 512, int pri = 0, int stack = 0);
01334 
01346         TCPSession(Semaphore *start, TCPSocket &server, int size = 512, 
01347                    int pri = 0, int stack = 0);
01348 };
01349 
01350 class SocketPort;
01351 class SocketService;
01352 
01372 class SocketPort : public Socket, public TimerPort
01373 {
01374 private:
01375         SocketPort *next, *prev;
01376         SocketService *service;
01377         struct timeval porttimer;
01378 #ifdef __CCXX_USE_POLL
01379         struct pollfd   * ufd;
01380 #endif
01381         bool detect_pending;
01382         bool detect_output;
01383         bool detect_disconnect;
01384         
01385         friend class SocketService;
01386 
01387 protected:
01396         SocketPort(SocketService *svc, TCPSocket &tcp);
01397 
01406         SocketPort(SocketService *svc, const InetAddress &ia, tpport_t port);
01407 
01413          void Attach( SocketService* svc );
01414 
01415 
01420         virtual ~SocketPort();
01421 
01426         void setDetectPending( bool );
01427         
01431         bool getDetectPending( void ) const
01432                 { return detect_pending; }
01433         
01438         void setDetectOutput( bool );
01439         
01443         bool getDetectOutput( void ) const
01444                 { return detect_output; }
01445 
01450         virtual void Expired(void)
01451                 {return;};
01452 
01457         virtual void Pending(void)
01458                 {return;};
01459 
01464         virtual void Output(void)
01465                 {return;};
01466 
01471         virtual void Disconnect(void)
01472                 {return;};
01473 
01484         sockerror_t Connect(const InetAddress &ia, tpport_t port);
01485 
01495         inline int Send(void *buf, int len)
01496                 {return ::send(so, (char *)buf, len, 0);};
01497 
01506         inline int Recv(void *buf, size_t len)
01507                 {return ::recv(so, (char *)buf, len, 0);};
01508 
01517         inline int Peek(void *buf, size_t len)
01518                 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
01519 
01520 public:
01528         void setTimer(timeout_t timeout = 0);
01529 
01537         void incTimer(timeout_t timeout);
01538 };
01539 
01552 class SocketService : public Thread, private Mutex
01553 {
01554 private:
01555         fd_set connect;
01556         int iosync[2];
01557         int hiwater;
01558         int count;
01559         SocketPort *first, *last;
01560 
01566         void Attach(SocketPort *port);
01572         void Detach(SocketPort *port);
01573         
01577         void Run(void);
01578 
01579         friend class SocketPort;
01580 
01581 protected:
01587         virtual void OnUpdate(unsigned char buf)
01588                 {return;};
01589 
01595         virtual void OnEvent(void)
01596                 {return;};
01597 
01605         virtual void OnCallback(SocketPort *port)
01606                 {return;};
01607 
01608 public:
01619         void Update(unsigned char flag = 0xff);
01620 
01627         SocketService(int pri = 0);
01628 
01633         ~SocketService();
01634 
01641         inline int getCount(void) const
01642                 {return count;};
01643 };
01644 
01645 ostream &operator<<(ostream &os, const InetAddress &ia);
01646 
01647 inline struct in_addr getaddress(const InetAddress &ia)
01648         {return ia.getAddress();};
01649 
01650 #ifdef  __CCXX_NAMESPACE_H__
01651 #undef  __CCXX_NAMESPACE_H__
01652 #include <cc++/namespace.h>
01653 #endif
01654 
01655 #endif
01656 

Generated at Fri Dec 15 07:08:32 2000 for CommonC++ by doxygen1.2.1 written by Dimitri van Heesch, © 1997-2000