|
|
// Copyright (C) 1999-2001 Open Source Telecom Corporation. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // As a special exception to the GNU General Public License, permission is // granted for additional uses of the text contained in its release // of Common C++. // // The exception is that, if you link the Common C++ library with other files // to produce an executable, this does not by itself cause the // resulting executable to be covered by the GNU General Public License. // Your use of that executable is in no way restricted on account of // linking the Common C++ library code into it. // // This exception does not however invalidate any other reasons why // the executable file might be covered by the GNU General Public License. // // This exception applies only to the code released under the // name Common C++. If you copy code from other releases into a copy of // Common C++, as the General Public License permits, the exception does // not apply to the code that you add in this way. To avoid misleading // anyone as to the status of such modified files, you must delete // this exception notice from them. // // If you write modifications of your own for Common C++, it is your choice // whether to permit this exception to apply to your modifications. // If you do not wish that, delete this exception notice. #ifndef __CCXX_SOCKET_H__ #define __CCXX_SOCKET_H__ #ifndef CCXX_CONFIG_H_ #include#endif #ifndef __CCXX_THREAD_H__ #include #endif #ifdef WIN32 #include #define TIMEOUT_INF ~((timeout_t) 0) typedef int socklen_t; #else #define INVALID_SOCKET -1 typedef int SOCKET; #endif #include #ifndef MSG_DONTWAIT #define MSG_DONTWAIT 0 #endif #ifdef CCXX_NAMESPACES namespace ost { #endif /** * used to enumerate type of socket I/O blocking - or non blocking */ enum sockstate_t { SOCKET_INITIAL, SOCKET_AVAILABLE, SOCKET_BOUND, SOCKET_CONNECTED, SOCKET_CONNECTING, SOCKET_STREAM }; typedef enum sockstate_t sockstate_t; enum sockerror_t { SOCKET_SUCCESS = 0, SOCKET_CREATE_FAILED, SOCKET_COPY_FAILED, SOCKET_INPUT_ERROR, SOCKET_INPUT_INTERRUPT, SOCKET_RESOURCE_FAILURE, SOCKET_OUTPUT_ERROR, SOCKET_OUTPUT_INTERRUPT, SOCKET_NOT_CONNECTED, SOCKET_CONNECT_REFUSED, SOCKET_CONNECT_REJECTED, SOCKET_CONNECT_TIMEOUT, SOCKET_CONNECT_FAILED, SOCKET_CONNECT_INVALID, SOCKET_CONNECT_BUSY, SOCKET_CONNECT_NOROUTE, SOCKET_BINDING_FAILED, SOCKET_BROADCAST_DENIED, SOCKET_ROUTING_DENIED, SOCKET_KEEPALIVE_DENIED, SOCKET_SERVICE_DENIED, SOCKET_SERVICE_UNAVAILABLE, SOCKET_MULTICAST_DISABLED, SOCKET_TIMEOUT_ERROR, SOCKET_NODELAY_ERROR, SOCKET_EXTENDED_ERROR }; typedef enum sockerror_t sockerror_t; enum socktos_t { SOCKET_IPTOS_LOWDELAY, SOCKET_IPTOS_THROUGHPUT, SOCKET_IPTOS_RELIABILITY, SOCKET_IPTOS_MINCOST, SOCKET_IPTOS_INVALID }; typedef enum socktos_t socktos_t; enum sockpend_t { SOCKET_PENDING_INPUT, SOCKET_PENDING_OUTPUT, SOCKET_PENDING_ERROR }; typedef enum sockpend_t sockpend_t; /** * Transport Protocol Ports. */ typedef unsigned short tpport_t; class CCXX_CLASS_EXPORT InetAddress; class CCXX_CLASS_EXPORT InetHostAddress; class CCXX_CLASS_EXPORT InetMaskAddress; class CCXX_CLASS_EXPORT BroadcastAddress; class CCXX_CLASS_EXPORT Socket; class CCXX_CLASS_EXPORT UDPSocket; class CCXX_CLASS_EXPORT UDPBroadcast; class CCXX_CLASS_EXPORT UDPTransmit; class CCXX_CLASS_EXPORT UDPReceive; class CCXX_CLASS_EXPORT UDPDuplex; class CCXX_CLASS_EXPORT TCPSocket; class CCXX_CLASS_EXPORT TCPStream; class CCXX_CLASS_EXPORT tcpstream; class CCXX_CLASS_EXPORT TCPSession; /** * Classes derived from InetAddress would require an specific * validator to pass to the InetAddress constructor. This is a base * class for classes of function objects used by such derived classes. * * @author Federico Montesino * @short Abstract base class for derived inet addresses validators. */ class InetAddrValidator { public: /** * Constructor. Does not deal with any state. */ InetAddrValidator() { }; /** * Pure virtual application operator. Apply the validation * algorithm specific to derived classes. */ inline virtual void operator()(const in_addr address) const = 0; }; /** * Class for the function object that validates multicast addresses. * Implements a specific application operator to validate multicast * addresses. * * @author Federico Montesino * @short Validating class specialized for multicast addresses. */ class InetMcastAddrValidator: public InetAddrValidator { public: /** * Constructor. Does not deal with any state. */ InetMcastAddrValidator(){}; /** * Application operator. Apply the validation algorithm * specific to multicast addresses */ inline void operator()(const in_addr address) const; private: #if __BYTE_ORDER == __BIG_ENDIAN enum { MCAST_VALID_MASK = 0xF0000000, MCAST_VALID_VALUE = 0xE0000000 }; #else enum { MCAST_VALID_MASK = 0x000000F0, MCAST_VALID_VALUE = 0x000000E0 }; #endif }; /** * The network name and address objects are all derived from a common * InetAddress base class. Specific classes, such as InetHostAddress, * InetMaskAddress, etc, are defined from InetAddress entirely so that the * manner a network address is being used can easily be documented and * understood from the code and to avoid common errors and accidental misuse * of the wrong address object. For example, a "connection" to something * that is declared as a "InetHostAddress" can be kept type-safe from a * "connection" accidently being made to something that was declared a * "InetBroadcastAddress". * * @author David Sugar * @short Internet Address binary data type. */ class InetAddress { private: // The validator given to an InetAddress object must not be a // transient object, but that must exist at least until the // last address object of its kind is deleted. This is an // artifact to be able to do specific checks for derived // classes inside constructors. const InetAddrValidator *validator; protected: struct in_addr * ipaddr; size_t addr_count; #if defined(WIN32) static MutexCounter counter; #else static Mutex mutex; #endif /** * Sets the IP address from a string representation of the * numeric address, ie "127.0.0.1" * * @param host The string representation of the IP address * @return true if successful */ bool setIPAddress(const char *host); /** * Used to specify a host name or numeric internet address. * * @param host The string representation of the IP address or * a hostname, , if NULL, it will default to INADDR_ANY */ void setAddress(const char *host); public: /** * Create an Internet Address object with an empty (0.0.0.0) * address. * * @param optional validator function object, intended for * derived classes. */ InetAddress(const InetAddrValidator *validator = NULL); /** * Convert the system internet address data type (struct in_addr) * into a Common C++ InetAddress object. * * @param addr struct of system used binary internet address. * @param optional validator function object, intended for * derived classes. */ InetAddress(struct in_addr addr, const InetAddrValidator *validator = NULL); /** * Convert a null terminated ASCII host address string * (example: "127.0.0.1") or host address name (example: * "www.voxilla.org") directly into a Common C++ InetAddress * object. * * @param address null terminated C string. * @param optional validator function object, intended for * derived classes. */ InetAddress(const char *address, const InetAddrValidator *validator = NULL); /** * Copy constructor */ InetAddress(const InetAddress &rhs); /** * Destructor */ virtual ~InetAddress(); /** * Provide a string representation of the value (Internet Address) * held in the InetAddress object. * * @return string representation of InetAddress. */ const char *getHostname(void) const; /** * May be used to verify if a given InetAddress returned * by another function contains a "valid" address, or "0.0.0.0" * which is often used to mark "invalid" InetAddress values. * * @return true if address != 0.0.0.0. */ bool isInetAddress(void) const; /** * Provide a low level system usable struct in_addr object from * the contents of InetAddress. This is needed for services such * as bind() and connect(). * * @return system binary coded internet address. */ struct in_addr getAddress(void) const; /** * Provide a low level system usable struct in_addr object from * the contents of InetAddress. This is needed for services such * as bind() and connect(). * * @param i for InetAddresses with multiple addresses, returns the * address at this index. User should call getAddressCount() * to determine the number of address the object contains. * @return system binary coded internet address. If parameter i is * out of range, the first address is returned. */ struct in_addr getAddress(size_t i) const; /** * Returns the number of internet addresses that an InetAddress object * contains. This usually only happens with InetHostAddress objects * where multiple IP addresses are returned for a DNS lookup */ size_t getAddressCount() const { return addr_count; } InetAddress &operator=(const char *str); InetAddress &operator=(struct in_addr addr); InetAddress &operator=(const InetAddress &rhs); /** * Allows assignment from the return of functions like * inet_addr() or htonl() */ InetAddress &operator=(unsigned long addr); inline bool operator!() const {return !isInetAddress();}; /** * Compare two internet addresses to see if they are equal * (if they specify the physical address of the same internet host). * * If there is more than one IP address in either InetAddress object, * this will return true if all of the IP addresses in the smaller * are in the larger in any order. */ bool operator==(const InetAddress &a) const; /** * Compare two internet addresses to see if they are not * equal (if they each refer to unique and different physical * ip addresses). * * This is implimented in terms of operator== */ bool operator!=(const InetAddress &a) const; }; /** * Internet addresses used specifically as masking addresses (such as " * 255.255.255.0") are held in the InetMaskAddress derived object. The * seperate class is used so that C++ type casting can automatically * determine when an InetAddress object is really a mask address object * rather than simply using the base class. This also allows manipulative * operators for address masking to operate only when presented with a * Masked address as well as providing cleaner and safer source. * * @author David Sugar * @short Internet Address Mask such as subnet masks. */ class InetMaskAddress : public InetAddress { public: /** * Create the mask from a null terminated ASCII string such as * "255.255.255.128". * * @param mask null terminated ASCII mask string. */ InetMaskAddress(const char *mask); /** * Masks are usually used to coerce host addresses into a specific * router or class domain. This can be done by taking the Inet * Host Address object and "and"ing it with an address mask. This * operation can be directly expressed in C++ through the & operator. * * @return a internet host address that has been masked. * @param addr host address to be masked by subnet. * @param mask inetnet mask address object to mask by. */ friend InetHostAddress operator&(const InetHostAddress &addr, const InetMaskAddress &mask); /** * Allows assignment from the return of functions like * inet_addr() or htonl() */ InetAddress &operator=(unsigned long addr) { return InetAddress::operator =(addr); } }; /** * This object is used to hold the actual and valid internet address of a * specific host machine that will be accessed through a socket. * * @author David Sugar * @short Address of a specific Internet host machine. */ class InetHostAddress : public InetAddress { public: /** * Create a new host address for a specific internet host. The * internet host can be specified in a null terminated ASCII * string and include either the physical host address or the * DNS name of a host machine. Hence, an InetHostAddress * ("www.voxilla.org") can be directly declaired in this manner. * * Defaults to the IP address that represents the interface matching * "gethostname()". * * @param host dns or physical address of an Internet host. */ InetHostAddress(const char *host = NULL); /** * Convert a system socket binary address such as may be * returned through the accept() call or getsockpeer() into * an internet host address object. * * @param addr binary address of internet host. */ InetHostAddress(struct in_addr addr); /** * Allows assignment from the return of functions like * inet_addr() or htonl() */ InetAddress &operator=(unsigned long addr) { return InetAddress::operator =(addr); } /** * Mask the internet host address object with a network mask address. * This is commonly used to coerce an address by subnet. */ InetHostAddress &operator&=(const InetMaskAddress &mask); friend class InetMaskAddress; friend InetHostAddress operator&(const InetHostAddress &addr, const InetMaskAddress &mask); }; /** * The broadcast address object is used to store the broadcast address for * a specific subnet. This is commonly used for UDP broadcast operations. */ class BroadcastAddress : public InetAddress { public: /** * Specify the physical broadcast address to use and create a new * broadcast address object based on a null terminated ASCII * string. * * @param net null terminated ASCII network address. */ BroadcastAddress(const char *net = "255.255.255.255"); }; /** * A specialization of InetAddress that provides address validation * for multicast addresses. Whenever its value changes the new value * is checked to be in the range from 224.0.0.1 through * 239.255.255.255. If it is not, an exception is thrown. * * @short A multicast network address. * @author Federico Montesino */ class InetMcastAddress: public InetAddress { public: /** * Create an Internet Multicast Address object with an empty * (0.0.0.0) address. */ InetMcastAddress(); /** * Convert the system internet address data type (struct in_addr) * into a Common C++ InetMcastAddress object. * * @param address struct of system used binary internet address. */ InetMcastAddress(const struct in_addr address); /** * Convert a null terminated ASCII multicast address string * (example: "224.0.0.1") or multicast name string (example: * "sap.mcast.net") directly into a Common C++ * InetMcastAddress object. Works like InetAddress(const * char*). * * @param address null terminated C string. */ InetMcastAddress(const char *address); private: /** * Check the address in addr
is a valid multicast * address. In case not, throws an exception. * * @param address a system network address * @return true if validation succeeded */ static const InetMcastAddrValidator validator; }; /** * The Socket is used as the base for all Internet protocol services * under Common C++. A socket is a system resource (or winsock descriptor) * that occupies a specific port address (and may be bound to a specific * network interface) on the local machine. The socket may also be * directly connected to a specific socket on a remote internet host. * * This base class is not directly used, but is * provided to offer properties common to other Common C++ socket classes, * including the socket exception model and the ability to set socket * properties such as QoS, "sockopts" properties like Dont-Route * and Keep-Alive, etc. * * * @author David Sugar
* @short base class of all sockets. */ class Socket { private: // used by exception handlers.... mutable sockerror_t errid; mutable const char *errstr; void setSocket(void); protected: mutable struct { bool thrown: 1; bool broadcast: 1; bool route: 1; bool keepalive: 1; bool loopback: 1; bool multicast: 1; bool completion: 1; bool linger: 1; unsigned ttl: 8; } flags; /** * the actual socket descriptor, in Windows, unlike posix it * *cannot* be used as an file descriptor * that way madness lies -- jfc */ SOCKET so; sockstate_t state; /** * This service is used to throw all socket errors which usually * occur during the socket constructor. * * @param error defined socket error id. * @param errstr string or message to pass. */ sockerror_t Error(sockerror_t error, char *errstr = NULL) const; /** * This service is used to throw application defined socket errors * where the application specific error code is a string. * * @param errstr string or message to pass. */ inline void Error(char *estr) {Error(SOCKET_EXTENDED_ERROR, estr);}; /** * This service is used to turn the error handler on or off for * "throwing" exceptions by manipulating the thrown flag. * * @param true to enable handler. */ inline void setError(bool enable) {flags.thrown = !enable;}; /** * Used as the default destructor for ending a socket. This * will cleanly terminate the socket connection. It is provided * for use in derived virtual destructors. */ void endSocket(void); /** * Used as a common handler for connection failure processing. * * @return correct failure code to apply. */ sockerror_t connectError(void); /** * Set the subnet broadcast flag for the socket. This enables * sending to a subnet and may require special image privileges * depending on the operating system. * * @return 0 (SOCKET_SUCCESS) on success, else error code. * @param enable when set to true. */ sockerror_t setBroadcast(bool enable); /** * Setting multicast binds the multicast interface used for * the socket to the interface the socket itself has been * implicitly bound to. It is also used as a check flag * to make sure multicast is enabled before multicast * operations are used. * * @return 0 (SOCKET_SUCCESS) on success, else error code. * @param enable when set to true. */ sockerror_t setMulticast(bool enable); /** * Set the multicast loopback flag for the socket. Loopback * enables a socket to hear what it is sending. * * @return 0 (SOCKET_SUCCESS) on success, else error code. * @param enable when set to true. */ sockerror_t setLoopback(bool enable); /** * Set the multicast time to live for a multicast socket. * * @return 0 (SOCKET_SUCCESS) on success, else error code. * @param time to live. */ sockerror_t setTimeToLive(unsigned char ttl); /** * Join a multicast group. * * @return 0 (SOCKET_SUCCESS) on success, else error code. * @param ia address of multicast group to join. */ sockerror_t Join(const InetMcastAddress &ia); /** * Drop membership from a multicast group. * * @return 0 (SOCKET_SUCCESS) on success, else error code. * @param address of multicast group to drop. */ sockerror_t Drop(const InetMcastAddress &ia); /** * Set the socket routing to indicate if outgoing messages * should bypass normal routing (set false). * * @return 0 on success. * @param enable normal routing when set to true. */ sockerror_t setRouting(bool enable); /** * Enable/disable delaying packets (Nagle algorithm) * * @return 0 on success. * @param disable Nagle algorithm when set to true. */ sockerror_t setNoDelay(bool enable); /** * An unconnected socket may be created directly on the local * machine. Sockets can occupy both the internet domain (AF_INET) * and UNIX socket domain (AF_UNIX) under unix. The socket type * (SOCK_STREAM, SOCK_DGRAM) and protocol may also be specified. * If the socket cannot be created, an exception is thrown. * * @param domain socket domain to use. * @param type base type and protocol family of the socket. * @param protocol specific protocol to apply. */ Socket(int domain, int type, int protocol = 0); /** * A socket object may be created from a file descriptor when that * descriptor was created either through a socket() or accept() * call. This constructor is mostly for internal use. * * @param fd file descriptor of an already existing socket. */ Socket(SOCKET fd); /** * A socket can also be constructed from an already existing * Socket object. The socket file descriptor is dup()'d. This * does not exist under win32. * * @param source of existing socket to clone. */ Socket(const Socket &source); /** * Process a logical input line from a socket descriptor * directly. * * @param pointer to string. * @param maximum length to read. * @param timeout for pending data in milliseconds. * @return number of bytes actually read. */ ssize_t Readline(char *buf, size_t len, timeout_t timeout = 0); public: /** * The socket base class may be "thrown" as a result of an * error, and the "catcher" may then choose to destroy the * object. By assuring the socket base class is a virtual * destructor, we can assure the full object is properly * terminated. */ virtual ~Socket(); /** * Sockets may also be duplicated by the assignment operator. */ Socket &operator=(const Socket &from); /** * May be used to examine the origin of data waiting in the * socket receive queue. This can tell a TCP server where pending * "connect" requests are coming from, or a UDP socket where it's * next packet arrived from. * * @param ptr to port number of sender. * @return host address, test with "isInetAddress()". */ InetHostAddress getSender(tpport_t *port = NULL) const; /** * Get the host address and port of the socket this socket * is connected to. If the socket is currently not in a * connected state, then a host address of 0.0.0.0 is * returned. * * @param ptr to port number of remote socket. * @return host address of remote socket. */ InetHostAddress getPeer(tpport_t *port = NULL) const; /** * Get the local address and port number this socket is * currently bound to. * * @param ptr to port number on local host. * @return host address of interface this socket is bound to. */ InetHostAddress getLocal(tpport_t *port = NULL) const; /** * Used to specify blocking mode for the socket. A socket * can be made non-blocking by setting setCompletion(false) * or set to block on all access with setCompletion(true). * I do not believe this form of non-blocking socket I/O is supported * in winsock, though it provides an alternate asynchronous set of * socket services. * * @param mode specify socket I/O call blocking mode. */ void setCompletion(bool immediate); /** * Enable lingering sockets on close. * * @param specify linger enable. */ sockerror_t setLinger(bool linger); /** * Set the keep-alive status of this socket and if keep-alive * messages will be sent. * * @return 0 on success. * @param enable keep alive messages. */ sockerror_t setKeepAlive(bool enable); /** * Set packet scheduling on platforms which support ip quality * of service conventions. This effects how packets in the * queue are scheduled through the interface. * * @return 0 on success, error code on failure. * @param type of service enumerated type. */ sockerror_t setTypeOfService(socktos_t service); /** * Can test to see if this socket is "connected", and hence * whether a "catch" can safely call getPeer(). Of course, * an unconnected socket will return a 0.0.0.0 address from * getPeer() as well. * * @return true when socket is connected to a peer. */ bool isConnected(void) const; /** * Test to see if the socket is at least operating or if it * is mearly initialized. "initialized" sockets may be the * result of failed constructors. * * @return true if not in initial state. */ bool isActive(void) const; /** * Operator based testing to see if a socket is currently * active. */ bool operator!() const; /** * Return if broadcast has been enabled for the specified * socket. * * @return true if broadcast socket. */ inline bool isBroadcast(void) const {return flags.broadcast;}; /** * Return if socket routing is enabled. * * @return true if routing enabled. */ inline bool isRouted(void) const {return flags.route;}; /** * Often used by a "catch" to fetch the last error of a thrown * socket. * * @return error number of sockerror_t error. */ inline sockerror_t getErrorNumber(void) const {return errid;} /** * Often used by a "catch" to fetch the user set error string * of a thrown socket, but only if EXTENDED error codes are used. * * @return string for error message. */ inline const char *getErrorString(void) const {return errstr;} /** * Get the status of pending operations. This can be used to * examine if input or output is waiting, or if an error has * occured on the descriptor. * * @return true if ready, false on timeout. * @param ready check to perform. * @param timeout in milliseconds, inf. if not specified. */ virtual bool isPending(sockpend_t pend, timeout_t timeout = TIMEOUT_INF); }; /** * UDP sockets implement the TCP SOCK_DGRAM UDP protocol. They can be * used to pass unverified messages between hosts, or to broadcast a * specific message to an entire subnet. Please note that Streaming of * realtime data commonly use UDPDuplex related classes rather than * UDPSocket. * * In addition to connected TCP sessions, Common C++ supports UDP sockets and * these also cover a range of functionality. Like a TCPSocket, A UDPSocket * can be created bound to a specific network interface and/or port address, * though this is not required. UDP sockets also are usually either * connected or otherwise "associated" with a specific "peer" UDP socket. * Since UDP sockets operate through discreet packets, there are no streaming * operators used with UDP sockets. * * In addition to the UDP "socket" class, there is a "UDPBroadcast" class. * The UDPBroadcast is a socket that is set to send messages to a subnet as a * whole rather than to an individual peer socket that it may be associated * with. * * UDP sockets are often used for building "realtime" media streaming * protocols and full duplex messaging services. When used in this manner, * typically a pair of UDP sockets are used together; one socket is used to * send and the other to receive data with an associated pair of UDP sockets * on a "peer" host. This concept is represented through the Common C++ * UDPDuplex object, which is a pair of sockets that communicate with another * UDPDuplex pair. * * * @author David Sugar * @short Unreliable Datagram Protocol sockets. */ class UDPSocket : public Socket { private: inline sockerror_t setKeepAlive(bool enable) {return Socket::setKeepAlive(enable);}; protected: struct sockaddr_in peer; public: /** * Create an unbound UDP socket, mostly for internal use. */ UDPSocket(void); /** * Create a UDP socket and bind it to a specific interface * and port address so that other UDP sockets on remote * machines (or the same host) may find and send UDP messages * to it. On failure to bind, an exception is thrown. * * @param bind address to bind this socket to. * @param port number to bind this socket to. */ UDPSocket(const InetAddress &bind, tpport_t port); /** * Destroy a UDP socket as a socket. */ virtual ~UDPSocket(); /** * set the peer address to send message packets to. This can be * set before every Send() call if nessisary. * * @param host address to send packets to. * @param port number to deliver packets to. */ void setPeer(const InetHostAddress &host, tpport_t port); /** * Send a message packet to a peer host. * * @param pointer to packet buffer to send. * @param len of packet buffer to send. * @return number of bytes sent. */ inline int Send(const void *buf, size_t len) {return ::sendto(so, (const char*)buf, len, 0, (struct sockaddr *)&peer, (socklen_t)sizeof(peer));}; /** * Receive a message from any host. * * @param pointer to packet buffer to receive. * @param len of packet buffer to receive. * @return number of bytes received. */ inline int Recv(void *buf, size_t len) {return ::recv(so, (char *)buf, len, 0);}; /** * Examine address of sender of next waiting packet. This also * sets "peer" address to the sender so that the next "send" * message acts as a "reply". This additional behavior overides * the standard socket getSender behavior. * * @param pointer to hold port number. */ InetHostAddress getPeer(tpport_t *port = NULL) const; /** * Examine contents of next waiting packet. * * @param pointer to packet buffer for contents. * @param len of packet buffer. * @return number of bytes examined. */ inline int Peek(void *buf, size_t len) {return ::recv(so, (char *)buf, len, MSG_PEEK);}; }; /** * Representing a UDP socket used for subnet broadcasts, this class * provides an alternate binding and setPeer() capability for UDP * sockets. * * @author David Sugar * @short Unreliable Datagram for subnet broadcasts. */ class UDPBroadcast : public UDPSocket { private: void setPeer(const InetHostAddress &ia, tpport_t port) {}; sockerror_t setBroadcast(bool enable) {return Socket::setBroadcast(enable);}; public: /** * Create and bind a subnet broadcast socket. * * @param address to bind socket under locally. * @param port to bind socket under locally. */ UDPBroadcast(const InetAddress &ia, tpport_t port); /** * Set peer by subnet rather than specific host. * * @param subnet of peer hosts to send to. * @param port number to use. */ void setPeer(const BroadcastAddress &subnet, tpport_t port); }; /** * Representing half of a two-way UDP connection, the UDP transmitter * can broadcast data to another selected peer host or to an entire * subnet. * * @author David Sugar * @short Unreliable Datagram Peer Associations. */ class UDPTransmit : private UDPSocket { private: /** * Common code for diferent flavours of Connect (host, broadcast, * multicast). * * @param ia network address to associate with * @param port port number to associate with */ sockerror_t CConnect(const InetAddress &ia, tpport_t port); protected: /** * Create a UDP transmitter. */ UDPTransmit(); /** * Create a UDP transmitter, bind it to a specific interface * and port address so that other UDP sockets on remote * machines (or the same host) may find and send UDP messages * to it, and associate it with a given port on a peer host. * On failure to bind, an exception is thrown. This class is * only used to build the UDP Duplex. * * @param bind address to bind this socket to. * @param port number to bind this socket to. * @param port number on peer host to associate with. */ UDPTransmit(const InetAddress &bind, tpport_t port = 5005); /** * Associate this socket with a specified peer host. The port * number from the constructor will be used. All UDP packets * will be sent to and received from the specified host. * * @return 0 on success, -1 on error. * @param host address to connect socket to. */ sockerror_t Connect(const InetHostAddress &host, tpport_t port); /** * Associate this socket with a subnet of peer hosts for * subnet broadcasting. The server must be able to assert * broadcast permission for the socket. * * @return 0 on success, -1 on error. * @param subnet address to broadcast into. */ sockerror_t Connect(const BroadcastAddress &subnet, tpport_t port); /** * Associate this socket with a multicast group. * * @return 0 on success, -1 on error. * @param mgroup address of the multicast group to send to. * @param port port number */ sockerror_t Connect(const InetMcastAddress &group, tpport_t port); /** * Disassociate this socket from any host connection. No data * should be read or written until a connection is established. */ sockerror_t Disconnect(void); /** * Transmit "send" to use "connected" send rather than sendto. * * @return number of bytes sent. * @param address of buffer to send. * @param len of bytes to send. */ inline int Send(const void *buf, int len) {return ::send(so, (const char *)buf, len, 0);} /** * Stop transmitter. */ inline void endTransmitter(void) {Socket::endSocket();} /* * Get transmitter socket. * * @return transmitter. */ inline SOCKET getTransmitter(void) {return so;}; inline sockerror_t setMulticast(bool enable) {return Socket::setMulticast(enable);}; inline sockerror_t setTimeToLive(unsigned char ttl) {return Socket::setTimeToLive(ttl);}; public: /** * Transmit "send" to use "connected" send rather than sendto. * * @note Windows does not support MSG_DONTWAIT, so it is defined * as 0 on that platform. * @return number of bytes sent. * @param address of buffer to send. * @param len of bytes to send. */ inline int Transmit(const char *buffer, size_t len) {return ::send(so, buffer, len, MSG_DONTWAIT);} /** * See if output queue is empty for sending more packets. * * @return true if output available. * @param timeout in milliseconds to wait. */ inline bool isOutputReady(unsigned long timeout = 0l) {return Socket::isPending(SOCKET_PENDING_OUTPUT, timeout);}; inline sockerror_t setRouting(bool enable) {return Socket::setRouting(enable);}; inline sockerror_t setTypeOfService(socktos_t tos) {return Socket::setTypeOfService(tos);}; inline sockerror_t setBroadcast(bool enable) {return Socket::setBroadcast(enable);}; }; /** * Representing half of a two-way UDP connection, the UDP receiver * can receive data from another peer host or subnet. This class is * used exclusivily to derive the UDPDuplex. * * @author David Sugar * @short Unreliable Datagram Peer Associations. */ class UDPReceive : private UDPSocket { protected: /** * Create a UDP receiver, bind it to a specific interface * and port address so that other UDP sockets on remote * machines (or the same host) may find and send UDP messages * to it, and associate it with a given port on a peer host. * On failure to bind, an exception is thrown. * * @param bind address to bind this socket to. * @param port number to bind this socket to. * @param port number on peer host to associate with. */ UDPReceive(const InetAddress &bind, tpport_t port); /** * Associate this socket with a specified peer host. The port * number from the constructor will be used. All UDP packets * will be sent received from the specified host. * * @return 0 on success, -1 on error. * @param host address to connect socket to. */ sockerror_t Connect(const InetHostAddress &host, tpport_t port); /** * Disassociate this socket from any host connection. No data * should be read or written until a connection is established. */ sockerror_t Disconnect(void); /** * Check for pending data. * * @return true if data is waiting. * @param timeout in milliseconds. */ bool isPendingReceive(timeout_t timeout) {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);}; /** * End receiver. */ inline void endReceiver(void) {Socket::endSocket();} inline SOCKET getReceiver(void) {return so;}; inline sockerror_t setRouting(bool enable) {return Socket::setRouting(enable);}; inline sockerror_t setMulticast(bool enable) {return Socket::setMulticast(enable);}; inline sockerror_t Join(const InetMcastAddress &ia) {return Socket::Join(ia);} inline sockerror_t Drop(const InetMcastAddress &ia) {return Socket::Drop(ia);} public: /** * Receive a data packet from the connected peer host. * * @return num of bytes actually received. * @param addr of data receive buffer. * @param size of data receive buffer. */ inline int Receive(void *buf, size_t len) {return ::recv(so, (char *)buf, len, 0);}; /** * See if input queue has data packets available. * * @return true if data packets available. * @param timeout in milliseconds. */ inline bool isInputReady(timeout_t timeout = TIMEOUT_INF) {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);}; }; /** * UDP duplex connections impliment a bi-directional point-to-point UDP * session between two peer hosts. Two UDP sockets are typically used * on alternating port addresses to assure that sender and receiver * data does not collide or echo back. A UDP Duplex is commonly used * for full duplex real-time streaming of UDP data between hosts. * * @author David Sugar * @short Unreliable Datagram Peer Associations. */ class UDPDuplex : public UDPTransmit, public UDPReceive { public: /** * Create a UDP duplex as a pair of UDP simplex objects * bound to alternating and interconnected port addresses. * * @param bind address to bind this socket to. * @param port number to bind sender. * @param port number to bind reciever. */ UDPDuplex(const InetAddress &bind, tpport_t port); /** * Associate the duplex with a specified peer host. Both * the sender and receiver will be interconnected with * the remote host. * * @return 0 on success, error code on error. * @param host address to connect socket to. * @param port number to connect socket to. */ sockerror_t Connect(const InetHostAddress &host, tpport_t port); /** * Disassociate this duplex from any host connection. No data * should be read or written until a connection is established. * * @return 0 on success, error code on error. */ sockerror_t Disconnect(void); }; /** * TCP sockets are used for stream based connected sessions between two * sockets. Both error recovery and flow control operate transparently * for a TCP socket connection. The TCP socket base class is primary used * to bind a TCP "server" for accepting TCP streams. * * An implicit and unique TCPSocket object exists in Common C++ to represent * a bound TCP socket acting as a "server" for receiving connection requests. * This class is not part of TCPStream because such objects normally perform * no physical I/O (read or write operations) other than to specify a listen * backlog queue and perform "accept" operations for pending connections. * The Common C++ TCPSocket offers a Peek method to examine where the next * pending connection is coming from, and a Reject method to flush the next * request from the queue without having to create a session. * * The TCPSocket also supports a "OnAccept" method which can be called when a * TCPStream related object is created from a TCPSocket. By creating a * TCPStream from a TCPSocket, an accept operation automatically occurs, and * the TCPSocket can then still reject the client connection through the * return status of it's OnAccept method. * * @author David Sugar * @short bound server for TCP streams and sessions. */ class TCPSocket : private Socket { protected: /** * A method to call in a derived TCPSocket class that is acting * as a server when a connection request is being accepted. The * server can implement protocol specific rules to exclude the * remote socket from being accepted by returning false. The * Peek method can also be used for this purpose. * * @return true if client should be accepted. * @param ia internet host address of the client. * @param port number of the client. */ virtual bool OnAccept(const InetHostAddress &ia, tpport_t port) {return true;}; friend class TCPStream; friend class SocketPort; friend class tcpstream; public: /** * A TCP "server" is created as a TCP socket that is bound * to a hardware address and port number on the local machine * and that has a backlog queue to listen for remote connection * requests. If the server cannot be created, an exception is * thrown. * * @param bind local ip address or interface to use. * @param port number to bind socket under. * @param backlog size of connection request queue. */ TCPSocket(const InetAddress &bind, tpport_t port, int backlog = 5); /** * Return address and port of next connection request. This * can be used instead of OnAccept() to pre-evaluate connection * requests. * * @return host requesting a connection. * @param port number of requestor. */ inline InetHostAddress getRequest(tpport_t *port = NULL) const {return Socket::getSender(port);}; /** * Used to reject the next incoming connection request. */ void Reject(void); /** * Used to get local bound address. */ inline InetHostAddress getLocal(tpport_t *port = NULL) const {return Socket::getLocal(port);}; /** * Used to wait for pending connection requests. */ inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF) /** not const -- jfc */ {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);} /** * Use base socket handler for ending this socket. */ virtual ~TCPSocket() {endSocket();}; }; /* :\projects\libraries\cplusplus\commonc++\win32\socket.h(357) : warning C4275: non dll-interface class 'streambuf' used as base for dll-interface class 'TCPStream' c:\program files\microsoft visual studio\vc98\include\streamb.h(69) : see declaration of 'streambuf' c:\projects\libraries\cplusplus\commonc++\win32\socket.h(358) : warning C4275: non dll-interface class 'iostream' used as base for dll-interface class 'TCPStream' c:\program files\microsoft visual studio\vc98\include\iostream.h(66) : see declaration of 'iostream' */ #ifdef _MSC_VER #pragma warning(disable:4275) // disable C4275 warning #endif /** * TCP streams are used to represent TCP client connections to a server * by TCP protocol servers for accepting client connections. The TCP * stream is a C++ "stream" class, and can accept streaming of data to * and from other C++ objects using the << and >> operators. * * TCPStream itself can be formed either by connecting to a bound network * address of a TCP server, or can be created when "accepting" a * network connection from a TCP server. * * @author David Sugar * @short streamable TCP socket connection. */ #if defined(STLPORT) || defined(__KCC) #define std::iostream std::iostream_withassign #endif #ifdef __KCC using std::iostream; #endif class TCPStream : public Socket, public std::streambuf, public std::iostream { private: inline sockerror_t setBroadcast(bool enable) {return Socket::setBroadcast(enable);}; inline InetHostAddress getSender(tpport_t *port) const {return InetHostAddress();}; int doallocate(); friend TCPStream& crlf(TCPStream&); friend TCPStream& lfcr(TCPStream&); protected: timeout_t timeout; int bufsize; char *gbuf, *pbuf; /** * The constructor required for "tcpstream", a more C++ style * version of the TCPStream class. */ TCPStream(bool throwflag = true); /** * Used to allocate the buffer space needed for iostream * operations. This function is called by the constructor. * * @param size of stream buffers from constructor. */ void Allocate(int size); /** * Used to terminate the buffer space and cleanup the socket * connection. This fucntion is called by the destructor. */ void endStream(void); /** * This streambuf method is used to load the input buffer * through the established tcp socket connection. * * @return char from get buffer, EOF if not connected. */ virtual int underflow(void); /** * This streambuf method is used for doing unbuffered reads * through the establish tcp socket connection when in interactive mode. * Also this method will handle proper use of buffers if not in * interative mode. * * @return char from tcp socket connection, EOF if not connected. */ int uflow(void); /** * This streambuf method is used to write the output * buffer through the established tcp connection. * * @param char to push through. * @return char pushed through. */ int overflow(int ch); /** * Create a TCP stream by connecting to a TCP socket (on * a remote machine). * * @param host address of remote TCP server. * @param port number to connect. * @param size of streaming input and output buffers. */ void Connect(const InetHostAddress &host, tpport_t port, int size); /** * Used in derived classes to refer to the current object via * it's iostream. For example, to send a set of characters * in a derived method, one might use *tcp() << "test". * * @return stream pointer of this object. */ std::iostream *tcp(void) {return ((std::iostream *)this);}; public: /** * Create a TCP stream by accepting a connection from a bound * TCP socket acting as a server. This performs an "accept" * call. * * @param size of streaming input and output buffers. * @param flag to throw errors. * @param timeout for all operations. */ TCPStream(TCPSocket &server, int size = 512, bool throwflag = true, timeout_t timeout = 0); /** * Create a TCP stream by connecting to a TCP socket (on * a remote machine). * * @param host address of remote TCP server. * @param port number to connect. * @param size of streaming input and output buffers. * @param flag to throw errors. * @param timeout for all operations. */ TCPStream(const InetHostAddress &host, tpport_t port, int size = 512, bool throwflag = true, timeout_t to = 0); /** * Set the I/O operation timeout for socket I/O operations. * * @param timeout to set. */ inline void setTimeout(timeout_t to) {timeout = to;}; /** * A copy constructor creates a new stream buffer. * * @param source of copy. * */ TCPStream(const TCPStream &source); /** * Flush and empty all buffers, and then remove the allocated * buffers. */ virtual ~TCPStream() {endStream();}; /** * Flushes the stream input and output buffers, writes * pending output. * * @return 0 on success. */ int sync(void); /** * Get the status of pending stream data. This can be used to * examine if input or output is waiting, or if an error or * disconnect has occured on the stream. If a read buffer * contains data then input is ready and if write buffer * contains data it is first flushed and then checked. */ bool isPending(sockpend_t pend, timeout_t timeout = TIMEOUT_INF); /** * Return the size of the current stream buffering used. * * @return size of stream buffers. */ int getBufferSize(void) const {return bufsize;}; }; /** * A more natural C++ "tcpstream" class for use by non-threaded * applications. This class behaves a lot more like fstream and * similar classes. * * @author David Sugar * @short C++ "fstream" style tcpstream class. */ class tcpstream : public TCPStream { public: /** * Construct an unopened "tcpstream" object. */ tcpstream(); /** * Construct and "open" (connect) the tcp stream to a remote * socket. * * @param addr string address in form addr:port. * @param buffer size for streaming (optional). */ tcpstream(const char *addr, int buffer = 512); /** * Construct and "accept" (connect) the tcp stream through * a server. * * @param tcp socket to accept from. * @param buffer size for streaming (optional). */ tcpstream(TCPSocket &tcp, int buffer = 512); /** * Open a tcp stream connection. This will close the currently * active connection first. * * @param addr string address in form addr:port. * @param buffer size for streaming (optional) */ void open(const char *addr, int buffer = 512); /** * Open a tcp stream connection by accepting a tcp socket. * * @param tcp socket to accept from. * @param buffer size for streaming (optional) */ void open(TCPSocket &tcp, int buffer = 512); /** * Close the active tcp stream connection. */ void close(void); /** * Test to see if stream is open. */ bool operator!() const; }; /** * The TCP session is used to primarily to represent a client connection * that can be managed on a seperate thread. The TCP session also supports * a non-blocking connection scheme which prevents blocking during the * constructor and moving the process of completing a connection into the * thread that executes for the session. * * @author David Sugar * @short Threaded streamable socket with non-blocking constructor. */ class TCPSession : public TCPStream, public Thread { protected: /** * Normally called during the thread Initial() method by default, * this will wait for the socket connection to complete when * connecting to a remote socket. One might wish to use * setCompletion() to change the socket back to blocking I/O * calls after the connection completes. To implement the * session one must create a derived class which implements * Run(). * * @return 0 if successful, -1 if timed out. * @param timeout to wait for completion in milliseconds. */ int WaitConnection(timeout_t timeout = TIMEOUT_INF); /** * The initial method is used to esablish a connection when * delayed completion is used. This assures the constructor * terminates without having to wait for a connection request * to complete. */ CCXX_MEMBER(void) Initial(void); /** * TCPSession derived objects can be freely created with "new" * and safely terminate their "Run" method on their own by * self-deleting when the thread terminates. */ CCXX_MEMBER(void) Final(void) {delete this;}; public: /** * Create a TCP socket that will be connected to a remote TCP * server and that will execute under it's own thread. * * @param host internet address of remote TCP server. * @param port number of remote server. * @param size of streaming buffer. * @param pri execution priority relative to parent. * @param stack allocation needed on some platforms. */ TCPSession(const InetHostAddress &host, tpport_t port, int size = 512, int pri = 0, int stack = 0); /** * Create a TCP socket from a bound TCP server by accepting a pending * connection from that server and execute a thread for the accepted * connection. * * @param server tcp socket to accept a connection from. * @param size of streaming buffer. * @param pri execution priority relative to parent. * @param stack allocation needed on some platforms. */ TCPSession(TCPSocket &server, int size = 512, int pri = 0, int stack = 0); }; extern CCXX_EXPORT(std::ostream&) operator<<(std::ostream &os, const InetAddress &ia); inline struct in_addr getaddress(const InetAddress &ia) {return ia.getAddress();} #if defined(WIN32) /** * class init_WSA used to initalise windows sockets specfifc stuff : there is * an MS - specific init sequence for Winsock 2 this class attempts to * initalise Winsock 2.2 - needed for non - blocking I/O. It will fall back * on 1.2 or lower if 2.0 or higher is not available, but < 2.0 does not * support non - blocking I/o * TO DO : might be an idea to have a method that reports version of * Winsock in use or a predicate to test if non - blocking is OK -- JFC */ class init_WSA { public: init_WSA(); ~init_WSA(); }; #else // !WIN32 class SocketService; /** * todo - SocketPort needs to be ported */ /** * The socket port is an internal class which is attached to and then * serviced by a specific SocketService "object". Derived versions of * this class offer specific functionality for specific protocols. Both * Common C++ supporting frameworks and application objects may be derived * from related protocol specific base classes. * * A special set of classes, "SocketPort" and "SocketService", exist * for building realtime streaming media servers on top of UDP and TCP * protocols. The "SocketPort" is used to hold a connected or associated TCP * or UDP socket which is being "streamed" and which offers callback methods * that are invoked from a "SocketService" thread. SocketService's can be * pooled into logical thread pools that can service a group of SocketPorts. * A millisecond accurate "timer" is associated with each SocketPort and can * be used to time synchronize SocketPort I/O operations. * * @author David Sugar * @short base class for realtime and thread pool serviced protocols. */ class SocketPort : public Socket, public TimerPort { private: SocketPort *next, *prev; SocketService *service; struct timeval porttimer; #ifdef __CCXX_USE_POLL struct pollfd * ufd; #endif bool detect_pending; bool detect_output; bool detect_disconnect; friend class SocketService; protected: /** * Construct an accepted TCP socket connection from a specific * bound TCP server. This is meant to derive advanced application * specific TCP servers that can be thread pooled. * * @param svc pool thread object. * @param tcp socket object to accept. */ SocketPort(SocketService *svc, TCPSocket &tcp); /** * Construct a bound UDP socket for use in deriving realtime * UDP streaming protocols handled by thread pool objects. * * @param svc pool thread object. * @param ia address of interface to bind. * @param port number to bind to. */ SocketPort(SocketService *svc, const InetAddress &ia, tpport_t port); /** * Attach yourself to the service pool thread object. The later version. * * @param svc pool thread object */ void Attach( SocketService* svc ); /** * Disconnect the socket from the service thread pool and * the remote connection. */ virtual ~SocketPort(); /** * Used to indicate if the service thread should monitor pending * data for us. */ void setDetectPending( bool ); /** * Get the current state of the DetectPending flag. */ bool getDetectPending( void ) const { return detect_pending; } /** * Used to indicate if output ready monitoring should be performed * by the service thread. */ void setDetectOutput( bool ); /** * Get the current state of the DetectOutput flag. */ bool getDetectOutput( void ) const { return detect_output; } /** * Called by the service thread pool when the objects timer * has expired. Used for timed events. */ virtual void Expired(void) {return;}; /** * Called by the service thread pool when input data is pending * for this socket. */ virtual void Pending(void) {return;}; /** * Called by the service thread pool when output data is pending * for this socket. */ virtual void Output(void) {return;}; /** * Called by the service thread pool when a disconnect has * occured. */ virtual void Disconnect(void) {return;}; /** * Connect a Socket Port to a known peer host. This is normally * used with the UDP constructor. This is also performed as a * non-blocking operation under Posix systems to prevent delays * in a callback handler. * * @return 0 if successful. * @param ia address of remote host or subnet. * @param port number of remote peer(s). */ sockerror_t Connect(const InetAddress &ia, tpport_t port); /** * Transmit "send" data to a connected peer host. This is not * public by default since an overriding protocol is likely to * be used in a derived class. * * @return number of bytes sent. * @param address of buffer to send. * @param len of bytes to send. */ inline int Send(const void *buf, int len) {return ::send(so, (const char *)buf, len, 0);}; /** * Receive a message from any host. This is used in derived * classes to build protocols. * * @param pointer to packet buffer to receive. * @param len of packet buffer to receive. * @return number of bytes received. */ inline int Recv(void *buf, size_t len) {return ::recv(so, (char *)buf, len, 0);}; /** * Examine the content of the next packet. This can be used * to build "smart" line buffering for derived TCP classes. * * @param pointer to packet buffer to examine. * @param len of packet buffer to examine. * @return number of bytes actually available. */ inline int Peek(void *buf, size_t len) {return ::recv(so, (char *)buf, len, MSG_PEEK);}; public: /** * Derived setTimer to notify the service thread pool of change * in expected timeout. This allows SocketService to * reschedule all timers. Otherwise same as TimerPort. * * @param timeout in milliseconds. */ void setTimer(timeout_t timeout = 0); /** * Derived incTimer to notify the service thread pool of a * change in expected timeout. This allows SocketService to * reschedule all timers. Otherwise same as TimerPort. * * @param timeout in milliseconds. */ void incTimer(timeout_t timeout); }; /** * The SocketService is a thread pool object that is meant to service * attached socket ports. Multiple pool objects may be created and * multiple socket ports may be attached to the same thread of execution. * This allows one to balance threads and sockets they service rather than * either using a single thread for all connections or a seperate thread * for each connection. Features can be added through supported virtual * methods. * * @author David Sugar * @short Thread pool service object for socket ports. */ class SocketService : public Thread, private Mutex { private: fd_set connect; int iosync[2]; int hiwater; int count; SocketPort *first, *last; /** * Attach a new socket port to this service thread. * * @param port of SocketPort derived object to attach. */ void Attach(SocketPort *port); /** * Detach a socket port from this service thread. * * @param port of SocketPort derived object to remove. */ void Detach(SocketPort *port); /** * The service thread itself. */ void Run(void); friend class SocketPort; protected: /** * Handles all requests other than "termination". * * @param request id as posted from Update(). */ virtual void OnUpdate(unsigned char buf) {return;}; /** * Called once each time the service thread is rescheduled. * This is called after the mutex is locked and can be used to * slip in additional processing. */ virtual void OnEvent(void) {return;}; /** * Called for each port that is being processed in response to * an event. This can be used to add additional notification * options during callback in combination with Update(). * * @param SocketPort who's callback events are being evaluated. */ virtual void OnCallback(SocketPort *port) {return;}; public: /** * Notify service thread that a port has been added or * removed, or a timer changed, so that a new schedule * can be computed for expiring attached ports. A "0" * is used to terminate the service thread, and additional * values can be specified which will be "caught" in the * OnUpdate() handler. * * @param Update flag value. */ void Update(unsigned char flag = 0xff); /** * Create a service thread for attaching socket ports. The * thread begins execution with the first attached socket. * * @param pri of this thread to run under. */ SocketService(int pri = 0); /** * Terminate the thread pool and eliminate any attached * socket ports. */ virtual ~SocketService(); /** * Get current reference count. This can be used when selecting * the least used service handler from a pool. * * @return count of active ports. */ inline int getCount(void) const {return count;}; }; #endif // !WIN32 #ifdef COMMON_STD_EXCEPTION class SockException : public IOException { public: SockException(std::string str) : IOException(str) {}; }; #endif #ifdef CCXX_NAMESPACES }; #endif #endif /** EMACS ** * Local variables: * mode: c++ * c-basic-offset: 8 * End: */
Generated by: dyfet on home on Wed Dec 5 07:05:45 2001, using kdoc 2.0a53. |