Google

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 #include "config.h"
00045 
00046 #if defined(WIN32)
00047 # ifndef __CCXX_THREAD_H__
00048 #  include <thread.h>
00049 # endif
00050 # include <winsock.h>
00051 # define TIMEOUT_INF ~((timeout_t) 0)
00052   typedef int socklen_t;
00053 #else
00054 # ifndef __CCXX_THREAD_H__
00055 #  include <cc++/thread.h>
00056 # elif defined(__CCXX_NAMESPACE_H__)
00057 #  include <cc++/macros.h>
00058 # endif
00059 # define INVALID_SOCKET -1
00060 # ifdef __EXPORT
00061 #  undef __EXPORT
00062 # endif
00063 # define __EXPORT
00064   typedef int SOCKET;
00065 #endif
00066 
00067 #include <iostream.h>
00068 
00069 #ifndef MSG_DONTWAIT
00070 #define MSG_DONTWAIT    0
00071 #endif
00072 
00077 typedef enum
00078 {
00079         SOCKET_COMPLETION_IMMEDIATE,
00080         SOCKET_COMPLETION_DELAYED
00081 } sockcomplete_t;
00082 
00083 typedef enum
00084 {
00085         SOCKET_INITIAL,
00086         SOCKET_AVAILABLE,
00087         SOCKET_BOUND,
00088         SOCKET_CONNECTED,
00089         SOCKET_CONNECTING,
00090         SOCKET_STREAM
00091 } sockstate_t;
00092 
00093 typedef enum
00094 {
00095         SOCKET_SUCCESS = 0,
00096         SOCKET_CREATE_FAILED,
00097         SOCKET_COPY_FAILED,
00098         SOCKET_INPUT_ERROR,
00099         SOCKET_INPUT_INTERRUPT,
00100         SOCKET_RESOURCE_FAILURE,
00101         SOCKET_OUTPUT_ERROR,
00102         SOCKET_OUTPUT_INTERRUPT,
00103         SOCKET_NOT_CONNECTED,
00104         SOCKET_CONNECT_REFUSED,
00105         SOCKET_CONNECT_REJECTED,
00106         SOCKET_CONNECT_TIMEOUT,
00107         SOCKET_CONNECT_FAILED,
00108         SOCKET_CONNECT_INVALID,
00109         SOCKET_CONNECT_BUSY,
00110         SOCKET_CONNECT_NOROUTE,
00111         SOCKET_BINDING_FAILED,
00112         SOCKET_BROADCAST_DENIED,
00113         SOCKET_ROUTING_DENIED,
00114         SOCKET_KEEPALIVE_DENIED,
00115         SOCKET_SERVICE_DENIED,
00116         SOCKET_SERVICE_UNAVAILABLE,
00117         SOCKET_MULTICAST_DISABLED,
00118         SOCKET_EXTENDED_ERROR
00119 } sockerror_t;
00120 
00121 typedef enum
00122 {
00123         SOCKET_IPTOS_LOWDELAY,
00124         SOCKET_IPTOS_THROUGHPUT,
00125         SOCKET_IPTOS_RELIABILITY,
00126         SOCKET_IPTOS_MINCOST,
00127         SOCKET_IPTOS_INVALID
00128 } socktos_t;
00129 
00130 typedef enum
00131 {
00132         SOCKET_PENDING_INPUT,
00133         SOCKET_PENDING_OUTPUT,
00134         SOCKET_PENDING_ERROR
00135 } sockpend_t;
00136 
00140 typedef unsigned short tpport_t;
00141 
00142 class __EXPORT InetAddress;
00143 class __EXPORT InetHostAddress;
00144 class __EXPORT InetMaskAddress;
00145 class __EXPORT BroadcastAddress;
00146 class __EXPORT Socket;
00147 class __EXPORT UDPSocket;
00148 class __EXPORT UDPBroadcast;
00149 class __EXPORT UDPTransmit;
00150 class __EXPORT UDPReceive;
00151 class __EXPORT UDPDuplex;
00152 class __EXPORT TCPSocket;
00153 class __EXPORT TCPStream;
00154 class __EXPORT tcpstream;
00155 class __EXPORT TCPSession;
00156 
00171 class InetAddress
00172 {
00173 protected:
00174         struct in_addr * ipaddr;
00175         size_t addr_count;
00176 #if defined(WIN32)
00177         static MutexCounter counter;
00178 #else
00179         static Mutex mutex;
00180 #endif
00181 
00188         bool setIPAddress(const char *host);
00189 
00196         void setAddress(const char *host);
00197 
00198 public:
00203         InetAddress();
00204 
00212         InetAddress(struct in_addr addr);
00213 
00220         InetAddress(const char *address);
00221 
00225         InetAddress(const InetAddress &rhs);
00226 
00230         virtual ~InetAddress();
00231 
00238         const char *getHostname(void) const;
00239 
00247         bool isInetAddress(void) const;
00248 
00256         struct in_addr getAddress(void) const;
00257 
00269         struct in_addr getAddress(size_t i) const;
00270 
00276         size_t getAddressCount() const { return addr_count; }
00277 
00278         InetAddress &operator=(const char *str);
00279         InetAddress &operator=(struct in_addr addr);
00280         InetAddress &operator=(const InetAddress &rhs);
00281 
00285         InetAddress &operator=(unsigned long addr);
00286 
00287         inline bool operator!() const
00288                 {return !isInetAddress();};
00289 
00298         bool operator==(const InetAddress &a) const;
00299 
00307         bool operator!=(const InetAddress &a) const;
00308 };      
00309 
00322 class InetMaskAddress : public InetAddress
00323 {
00324 public:
00331         InetMaskAddress(const char *mask);
00332 
00343         friend InetHostAddress operator&(const InetHostAddress &addr, 
00344                                          const InetMaskAddress &mask);
00345 
00349         InetAddress &operator=(unsigned long addr) 
00350         { return InetAddress::operator =(addr); }
00351 };
00352 
00360 class InetHostAddress : public InetAddress
00361 {
00362 public: 
00375         InetHostAddress(const char *host = NULL);
00376 
00384         InetHostAddress(struct in_addr addr);
00385 
00389         InetAddress &operator=(unsigned long addr) 
00390         { return InetAddress::operator =(addr); }
00391 
00396         InetHostAddress &operator&=(const InetMaskAddress &mask);
00397 
00398         friend class InetMaskAddress;
00399         friend InetHostAddress operator&(const InetHostAddress &addr, 
00400                                          const InetMaskAddress &mask);
00401 };
00402 
00407 class BroadcastAddress : public InetAddress
00408 {
00409 public:
00417         BroadcastAddress(const char *net = "255.255.255.255");
00418 };
00419 
00437 class Socket
00438 {
00439 private:
00440         // used by exception handlers....
00441         mutable sockerror_t errid;
00442         mutable const char *errstr;
00443 
00444         mutable struct
00445         {
00446                 bool thrown: 1;
00447                 bool broadcast: 1;
00448                 bool route: 1;
00449                 bool keepalive: 1;
00450                 bool loopback: 1;
00451                 bool multicast: 1;
00452                 unsigned ttl: 8;
00453         } flags;
00454 
00455         void setSocket(void);
00456 
00457 protected:
00463         SOCKET so;
00464         sockstate_t state;
00465 
00473         sockerror_t Error(sockerror_t error, char *errstr = NULL) const;
00474 
00481         inline void Error(char *estr)
00482                 {Error(SOCKET_EXTENDED_ERROR, estr);};
00483         
00490         inline void setError(bool enable)
00491                 {flags.thrown = !enable;};
00492 
00498         void endSocket(void);
00499 
00505         sockerror_t connectError(void);
00506 
00515         sockerror_t setBroadcast(bool enable);
00516 
00527         sockerror_t setMulticast(bool enable);
00528 
00536         sockerror_t setLoopback(bool enable);
00537 
00544         sockerror_t setTimeToLive(unsigned char ttl);
00545 
00552         sockerror_t Join(InetAddress &ia);
00553 
00560         sockerror_t Drop(InetAddress &ia);
00561 
00569         sockerror_t setRouting(bool enable);
00570 
00582         Socket(int domain, int type, int protocol = 0);
00583 
00591         Socket(SOCKET fd);
00592 
00600         Socket(const Socket &source);
00601 
00610         ssize_t Readline(char *buf, size_t len);
00611 
00612 public:
00620         virtual ~Socket()
00621                 {endSocket();};
00622 
00626         Socket &operator=(const Socket &from);
00627 
00637         InetHostAddress getSender(tpport_t *port = NULL) const;
00638 
00648         InetHostAddress getPeer(tpport_t *port = NULL) const;
00649 
00657         InetHostAddress getLocal(tpport_t *port = NULL) const;
00658         
00669         void setCompletion(sockcomplete_t completion);
00670 
00678         sockerror_t setKeepAlive(bool enable);
00679 
00688         sockerror_t setTypeOfService(socktos_t service);
00689 
00698         bool isConnected(void) const;
00699 
00707         bool isActive(void) const;
00708 
00713         bool operator!() const;
00714 
00721         inline bool isBroadcast(void) const
00722                 {return flags.broadcast;};
00723 
00729         inline bool isRouted(void) const
00730                 {return flags.route;};
00731 
00738         inline sockerror_t getErrorNumber(void) const {return errid;}
00739         
00746         inline const char *getErrorString(void) const {return errstr;}
00747 
00757         virtual bool isPending(sockpend_t pend, timeout_t timeout = TIMEOUT_INF);
00758 };
00759 
00792 class UDPSocket : public Socket
00793 {
00794 private:
00795         inline sockerror_t setKeepAlive(bool enable)
00796                 {return Socket::setKeepAlive(enable);};
00797 
00798 protected:
00799         struct sockaddr_in peer;
00800 
00801 public:
00805         UDPSocket(void);
00806 
00816         UDPSocket(const InetAddress &bind, tpport_t port);
00817 
00821         ~UDPSocket()
00822                 {endSocket();};
00823 
00831         void setPeer(const InetHostAddress &host, tpport_t port);
00832 
00840         inline int Send(void *buf, size_t len)
00841                 {return ::sendto(so, (const char *)buf, len, 0, (struct sockaddr *)&peer, (socklen_t)sizeof(peer));};
00842 
00850         inline int Recv(void *buf, size_t len)
00851                 {return ::recv(so, (char *)buf, len, 0);};
00852 
00861         InetHostAddress getPeer(tpport_t *port = NULL) const;
00862 
00870         inline int Peek(void *buf, size_t len)
00871                 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
00872 };
00873 
00874 
00883 class UDPBroadcast : public UDPSocket
00884 {
00885 private:
00886         void setPeer(const InetHostAddress &ia, tpport_t port) {};
00887 
00888         sockerror_t setBroadcast(bool enable)
00889                 {return Socket::setBroadcast(enable);};
00890 
00891 public:
00898         UDPBroadcast(const InetAddress &ia, tpport_t port);
00899 
00906         void setPeer(const BroadcastAddress &subnet, tpport_t port);
00907 };      
00908 
00917 class UDPTransmit : private UDPSocket
00918 {
00919 protected:
00923         UDPTransmit();
00924 
00937         UDPTransmit(const InetAddress &bind, tpport_t port = 5005);
00938 
00947         sockerror_t Connect(const InetHostAddress &host, tpport_t port);
00948 
00957         sockerror_t Connect(const BroadcastAddress &subnet, tpport_t port);
00958 
00963         sockerror_t Disconnect(void);
00964 
00972         inline int Send(void *buf, int len)
00973                 {return ::send(so, (char *)buf, len, 0);}
00974 
00978         inline void endTransmitter(void)
00979                 {Socket::endSocket();}
00980 
00981         /*
00982          * Get transmitter socket.
00983          *
00984          * @return transmitter.
00985          */
00986         inline SOCKET getTransmitter(void)
00987                 {return so;};
00988 
00989 public:
00999         inline int Transmit(const char *buffer, size_t len)
01000                 {return ::send(so, buffer, len, MSG_DONTWAIT);}
01001 
01008         inline bool isOutputReady(unsigned long timeout = 0l)
01009                 {return Socket::isPending(SOCKET_PENDING_OUTPUT, timeout);};
01010 
01011 
01012         inline sockerror_t setRouting(bool enable)
01013                 {return Socket::setRouting(enable);};
01014 
01015         inline sockerror_t setTypeOfService(socktos_t tos)
01016                 {return Socket::setTypeOfService(tos);};
01017 
01018         inline sockerror_t setBroadcast(bool enable)
01019                 {return Socket::setBroadcast(enable);};
01020 };
01021 
01030 class UDPReceive : private UDPSocket
01031 {
01032 protected:
01044         UDPReceive(const InetAddress &bind, tpport_t port);
01045 
01054         sockerror_t Connect(const InetHostAddress &host, tpport_t port);
01055 
01060         sockerror_t Disconnect(void);
01061 
01068         bool isPendingReceive(timeout_t timeout)
01069                 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);};
01070 
01074         inline void endReceiver(void)
01075                 {Socket::endSocket();}
01076 
01077         inline SOCKET getReceiver(void)
01078                 {return so;};
01079 
01080         inline sockerror_t setRouting(bool enable)
01081                 {return Socket::setRouting(enable);};
01082 
01083 public:
01091         inline int Receive(void *buf, size_t len)
01092                 {return ::recv(so, (char *)buf, len, 0);};
01093 
01100         inline bool isInputReady(timeout_t timeout = TIMEOUT_INF)
01101                 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);};
01102 };
01103 
01114 class UDPDuplex : public UDPTransmit, public UDPReceive
01115 {
01116 public:
01125         UDPDuplex(const InetAddress &bind, tpport_t port);
01126 
01136         sockerror_t Connect(const InetHostAddress &host, tpport_t port);
01137 
01144         sockerror_t Disconnect(void);
01145 };
01146 
01147 
01172 class TCPSocket : private Socket
01173 {
01174 protected:
01182         virtual bool OnAccept(const InetHostAddress &ia, short port) {
01183                 return false;
01184         }
01185 
01197         virtual bool OnAccept(const InetHostAddress &ia, tpport_t port)
01198                 {return true;};
01199 
01200         friend class TCPStream;
01201         friend class SocketPort;
01202         friend class tcpstream;
01203 
01204 public:
01216         TCPSocket(const InetAddress &bind, tpport_t port, int backlog = 5);
01217         
01226         inline InetHostAddress getRequest(tpport_t *port = NULL) const
01227                 {return Socket::getSender(port);};
01228 
01232         void Reject(void);
01233 
01237         inline InetHostAddress getLocal(tpport_t *port = NULL) const
01238                 {return Socket::getLocal(port);};
01239 
01243         inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF) 
01244                 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);}
01245 
01249         ~TCPSocket()
01250                 {endSocket();};
01251 };
01252 
01253 /*
01254 :\projects\libraries\cplusplus\commonc++\win32\socket.h(357) : warning C4275: non dll-interface class 'streambuf' used as base for dll-interface class 'TCPStream'
01255         c:\program files\microsoft visual studio\vc98\include\streamb.h(69) : see declaration of 'streambuf'
01256 c:\projects\libraries\cplusplus\commonc++\win32\socket.h(358) : warning C4275: non dll-interface class 'iostream' used as base for dll-interface class 'TCPStream'
01257         c:\program files\microsoft visual studio\vc98\include\iostream.h(66) : see declaration of 'iostream'
01258 */
01259 
01260 #ifndef __KCC
01261 #pragma warning(disable:4275) // disable C4275 warning
01262 #endif
01263 
01277 #if defined(STLPORT) || defined(__KCC)
01278 #define iostream iostream_withassign
01279 #endif
01280 #ifdef  __KCC
01281 using std::iostream;
01282 #endif
01283 class TCPStream : public Socket, public streambuf, public iostream
01284 {
01285 private:
01286         inline sockerror_t setBroadcast(bool enable)
01287                 {return Socket::setBroadcast(enable);};
01288 
01289         inline InetHostAddress getSender(tpport_t *port) const
01290                 {return InetHostAddress();};
01291 
01292         int doallocate();
01293 
01294         friend TCPStream& crlf(TCPStream&);
01295         friend TCPStream& lfcr(TCPStream&);
01296 
01297 protected:
01298         int bufsize;
01299         char *gbuf, *pbuf;
01300 
01305         TCPStream();
01306 
01313         void Allocate(int size);
01314 
01319         void endStream(void);
01320 
01327         virtual int underflow(void);
01328 
01337         int uflow(void);
01338 
01346         int overflow(int ch);
01347 
01356         void Connect(const InetHostAddress &host, tpport_t port, int size);
01357 
01365         iostream *tcp(void)
01366                 {return ((iostream *)this);};
01367 
01368 public:
01376         TCPStream(TCPSocket &server, int size = 512);
01377 
01386         TCPStream(const InetHostAddress &host, tpport_t port, int size = 512);
01387 
01394         TCPStream(const TCPStream &source);
01395 
01400         ~TCPStream()
01401                 {endStream();};
01402 
01409         int sync(void);
01410 
01418         bool isPending(sockpend_t pend, timeout_t timeout = TIMEOUT_INF);
01419 
01425         int getBufferSize(void) const
01426                 {return bufsize;};
01427 };
01428 
01437 class tcpstream : public TCPStream
01438 {
01439 public:
01443         tcpstream();
01444 
01452         tcpstream(const char *addr, int buffer = 512);
01453 
01461         tcpstream(TCPSocket &tcp, int buffer = 512);
01462 
01470         void open(const char *addr, int buffer = 512);
01471 
01478         void open(TCPSocket &tcp, int buffer = 512);
01479 
01483         void close(void);
01484 
01488         bool operator!() const;
01489 };              
01490 
01501 class TCPSession : public TCPStream, public Thread
01502 {
01503 protected:
01516         int WaitConnection(timeout_t timeout = TIMEOUT_INF);
01517 
01524         void Initial(void);
01525 
01531         void Final(void)
01532                 {delete this;};
01533 public:
01545         TCPSession(Semaphore *start, const InetHostAddress &host, 
01546                    tpport_t port, int size = 512, int pri = 0, int stack = 0);
01547 
01559         TCPSession(Semaphore *start, TCPSocket &server, int size = 512, 
01560                    int pri = 0, int stack = 0);
01561 };
01562 
01563 extern __EXPORT ::ostream &operator<<(::ostream &os, const InetAddress &ia);
01564 
01565 inline struct in_addr getaddress(const InetAddress &ia)
01566         {return ia.getAddress();}
01567 
01568 #if defined(WIN32)
01569 
01583 class init_WSA
01584 {
01585 public:
01586         init_WSA();
01587 private:
01588         WSADATA                         wsaData;
01589 };
01590 
01591 #else // !WIN32
01592 
01593 class SocketService;
01594 
01614 class SocketPort : public Socket, public TimerPort
01615 {
01616 private:
01617         SocketPort *next, *prev;
01618         SocketService *service;
01619         struct timeval porttimer;
01620 #ifdef __CCXX_USE_POLL
01621         struct pollfd   * ufd;
01622 #endif
01623         bool detect_pending;
01624         bool detect_output;
01625         bool detect_disconnect;
01626         
01627         friend class SocketService;
01628 
01629 protected:
01638         SocketPort(SocketService *svc, TCPSocket &tcp);
01639 
01648         SocketPort(SocketService *svc, const InetAddress &ia, tpport_t port);
01649 
01655          void Attach( SocketService* svc );
01656 
01657 
01662         virtual ~SocketPort();
01663 
01668         void setDetectPending( bool );
01669         
01673         bool getDetectPending( void ) const
01674                 { return detect_pending; }
01675         
01680         void setDetectOutput( bool );
01681         
01685         bool getDetectOutput( void ) const
01686                 { return detect_output; }
01687 
01692         virtual void Expired(void)
01693                 {return;};
01694 
01699         virtual void Pending(void)
01700                 {return;};
01701 
01706         virtual void Output(void)
01707                 {return;};
01708 
01713         virtual void Disconnect(void)
01714                 {return;};
01715 
01726         sockerror_t Connect(const InetAddress &ia, tpport_t port);
01727 
01737         inline int Send(void *buf, int len)
01738                 {return ::send(so, (char *)buf, len, 0);};
01739 
01748         inline int Recv(void *buf, size_t len)
01749                 {return ::recv(so, (char *)buf, len, 0);};
01750 
01759         inline int Peek(void *buf, size_t len)
01760                 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
01761 
01762 public:
01770         void setTimer(timeout_t timeout = 0);
01771 
01779         void incTimer(timeout_t timeout);
01780 };
01781 
01794 class SocketService : public Thread, private Mutex
01795 {
01796 private:
01797         fd_set connect;
01798         int iosync[2];
01799         int hiwater;
01800         int count;
01801         SocketPort *first, *last;
01802 
01808         void Attach(SocketPort *port);
01814         void Detach(SocketPort *port);
01815         
01819         void Run(void);
01820 
01821         friend class SocketPort;
01822 
01823 protected:
01829         virtual void OnUpdate(unsigned char buf)
01830                 {return;};
01831 
01837         virtual void OnEvent(void)
01838                 {return;};
01839 
01847         virtual void OnCallback(SocketPort *port)
01848                 {return;};
01849 
01850 public:
01861         void Update(unsigned char flag = 0xff);
01862 
01869         SocketService(int pri = 0);
01870 
01875         ~SocketService();
01876 
01883         inline int getCount(void) const
01884                 {return count;};
01885 };
01886 
01887 #ifdef  __CCXX_NAMESPACE_H__
01888 #undef  __CCXX_NAMESPACE_H__
01889 #include <cc++/namespace.h>
01890 #endif
01891 
01892 #endif // !WIN32
01893 
01894 #endif
01895 

Generated at Fri Mar 23 10:47:54 2001 for CommonC++ by doxygen1.2.1 written by Dimitri van Heesch, © 1997-2000