diff --git a/net/CNetwork.h b/net/CNetwork.h index 1bc2e4e2..f1d674a0 100644 --- a/net/CNetwork.h +++ b/net/CNetwork.h @@ -31,8 +31,10 @@ typedef int ssize_t; # endif #endif +//! Networking functions class CNetwork { public: + // platform dependent types #if WINDOWS_LIKE typedef SOCKET Socket; typedef struct sockaddr Address; @@ -64,20 +66,39 @@ public: }; #endif - // manipulators + //! @name manipulators + //@{ + //! Initialize network subsystem + /*! + This \b must be called before any other calls to the network subsystem. + */ static void init(); + + //! Clean up network subsystem + /*! + This should be called when the network subsystem is no longer needed + and no longer in use. + */ static void cleanup(); // byte swapping functions + //! Swap bytes to network order static UInt32 swaphtonl(UInt32 hostlong); + //! Swap bytes to network order static UInt16 swaphtons(UInt16 hostshort); + //! Swap bytes to host order static UInt32 swapntohl(UInt32 netlong); + //! Swap bytes to host order static UInt16 swapntohs(UInt16 netshort); - // constants + //@} + //! @name constants + //@{ + //! The error type static const int Error; + //! The non-socket static const Socket Null; // getsockerror() constants @@ -108,6 +129,8 @@ public: kHNone = 0 }; + //@} + // socket interface (only available after init()) static Socket (PASCAL FAR *accept)(Socket s, Address FAR *addr, AddressLength FAR *addrlen); @@ -143,6 +166,7 @@ public: // convenience functions (only available after init()) + //! Set socket to (non-)blocking operation static int (PASCAL FAR *setblocking)(CNetwork::Socket s, bool blocking); #if WINDOWS_LIKE diff --git a/net/CNetworkAddress.h b/net/CNetworkAddress.h index 1fd60fd4..ed7be4cc 100644 --- a/net/CNetworkAddress.h +++ b/net/CNetworkAddress.h @@ -5,39 +5,73 @@ #include "CString.h" #include "BasicTypes.h" +//! Network address type +/*! +This class represents a network address. +*/ class CNetworkAddress { public: - // invalid address + /*! + Constructs the invalid address + */ CNetworkAddress(); - // wildcard address and given port. port must not be zero. + /*! + Construct the wildcard address with the given port. \c port must + not be zero. + */ CNetworkAddress(UInt16 port); - // given address and port. if hostname can be parsed as numerical - // address then that's how it's used, otherwise the hostname is - // looked up. if lookup fails then it throws XSocketAddress. if - // hostname ends in ":[0-9]+" then that suffix is extracted and - // used as the port, overridding the port parameter. neither - // port may be zero. + /*! + Construct the network address for the given \c hostname and \c port. + If \c hostname can be parsed as a numerical address then that's how + it's used, otherwise the host name is looked up. If the lookup fails + then this throws XSocketAddress. If \c hostname ends in ":[0-9]+" then + that suffix is extracted and used as the port, overridding the port + parameter. Neither the extracted port or \c port may be zero. + */ CNetworkAddress(const CString& hostname, UInt16 port); ~CNetworkAddress(); - // manipulators + //! @name accessors + //@{ - // accessors - - // returns true if this is not the invalid address + //! Check address validity + /*! + Returns true if this is not the invalid address. + */ bool isValid() const; - // get the address + //! Get address + /*! + Returns the address in the platform's native network address + structure. + */ const CNetwork::Address* getAddress() const; + + //! Get address length + /*! + Returns the length of the address in the platform's native network + address structure. + */ CNetwork::AddressLength getAddressLength() const; - // get the hostname and port (as provided in the c'tor) + //! Get hostname + /*! + Returns the hostname passed to the c'tor sans the port suffix. + */ CString getHostname() const; + + //! Get port + /*! + Returns the port passed to the c'tor as a suffix to the hostname, + if that existed, otherwise as passed directly to the c'tor. + */ UInt16 getPort() const; + //@} + private: CNetwork::Address m_address; CString m_hostname; diff --git a/net/CTCPListenSocket.h b/net/CTCPListenSocket.h index d89f0049..25c3a6ab 100644 --- a/net/CTCPListenSocket.h +++ b/net/CTCPListenSocket.h @@ -4,15 +4,15 @@ #include "IListenSocket.h" #include "CNetwork.h" +//! TCP listen socket +/*! +A listen socket using TCP. +*/ class CTCPListenSocket : public IListenSocket { public: CTCPListenSocket(); ~CTCPListenSocket(); - // manipulators - - // accessors - // ISocket overrides virtual void bind(const CNetworkAddress&); virtual void close(); diff --git a/net/CTCPSocket.h b/net/CTCPSocket.h index a38789df..d30f75e6 100644 --- a/net/CTCPSocket.h +++ b/net/CTCPSocket.h @@ -11,16 +11,16 @@ class CThread; class CBufferedInputStream; class CBufferedOutputStream; +//! TCP data socket +/*! +A data socket using TCP. +*/ class CTCPSocket : public IDataSocket { public: CTCPSocket(); CTCPSocket(CNetwork::Socket); ~CTCPSocket(); - // manipulators - - // accessors - // ISocket overrides virtual void bind(const CNetworkAddress&); virtual void close(); diff --git a/net/IDataSocket.h b/net/IDataSocket.h index faf645b8..f10854b4 100644 --- a/net/IDataSocket.h +++ b/net/IDataSocket.h @@ -6,19 +6,40 @@ class IInputStream; class IOutputStream; +//! Data stream socket interface +/*! +This interface defines the methods common to all network sockets that +represent a full-duplex data stream. +*/ class IDataSocket : public ISocket { public: - // manipulators + //! @name manipulators + //@{ - // connect the socket + //! Connect socket + /*! + Attempt to connect to a remote endpoint. This waits until the + connection is established or fails. If it fails it throws an + XSocketConnect exception. + + (cancellation point) + */ virtual void connect(const CNetworkAddress&) = 0; - // get the input and output streams for the socket. closing - // these streams closes the appropriate half of the socket. + //! Get input stream + /*! + Returns the input stream for reading from the socket. Closing this + stream will shutdown the socket for reading. + */ virtual IInputStream* getInputStream() = 0; + //! Get output stream + /*! + Returns the output stream for writing to the socket. Closing this + stream will shutdown the socket for writing. + */ virtual IOutputStream* getOutputStream() = 0; - // accessors + //@} // ISocket overrides virtual void bind(const CNetworkAddress&) = 0; diff --git a/net/IListenSocket.h b/net/IListenSocket.h index 51d73cfc..4b35f249 100644 --- a/net/IListenSocket.h +++ b/net/IListenSocket.h @@ -5,14 +5,26 @@ class IDataSocket; +//! Listen socket interface +/*! +This interface defines the methods common to all network sockets that +listen for incoming connections. +*/ class IListenSocket : public ISocket { public: - // manipulators + //! @name manipulators + //@{ - // wait for a connection + //! Accept connection + /*! + Wait for and accept a connection, returning a socket representing + the full-duplex data stream. + + (cancellation point) + */ virtual IDataSocket* accept() = 0; - - // accessors + + //@} // ISocket overrides virtual void bind(const CNetworkAddress&) = 0; diff --git a/net/ISocket.h b/net/ISocket.h index 8ca8fbf0..72790960 100644 --- a/net/ISocket.h +++ b/net/ISocket.h @@ -5,18 +5,28 @@ class CNetworkAddress; +//! Generic socket interface +/*! +This interface defines the methods common to all network sockets. +*/ class ISocket : public IInterface { public: - // manipulators + //! @name manipulators + //@{ - // bind the socket to a particular address + //! Bind socket to address + /*! + Binds the socket to a particular address. + */ virtual void bind(const CNetworkAddress&) = 0; - // close the socket. this will flush the output stream if it - // hasn't been closed yet. + //! Close socket + /*! + Closes the socket. This should flush the output stream. + */ virtual void close() = 0; - // accessors + //@} }; #endif diff --git a/net/XNetwork.h b/net/XNetwork.h index ac0e5a24..aa495655 100644 --- a/net/XNetwork.h +++ b/net/XNetwork.h @@ -4,29 +4,53 @@ #include "XBase.h" #include "CString.h" +//! Generic network exception +/*! +Network exceptions are thrown when initializing the network subsystem +and not during normal network use. +*/ class XNetwork : public XBase { }; +//! Network subsystem not available exception +/*! +Thrown when the network subsystem is unavailable, typically because +the necessary shared library is unavailable. +*/ class XNetworkUnavailable : public XNetwork { protected: // XBase overrides virtual CString getWhat() const throw(); }; +//! Network subsystem failed exception +/*! +Thrown when the network subsystem cannot be initialized. +*/ class XNetworkFailed : public XNetwork { protected: // XBase overrides virtual CString getWhat() const throw(); }; +//! Network subsystem vesion unsupported exception +/*! +Thrown when the network subsystem has a version incompatible with +what's expected. +*/ class XNetworkVersion : public XNetwork { public: XNetworkVersion(int major, int minor) throw(); - // accessors + //! @name accessors + //@{ + //! Get the network subsystem's major version int getMajor() const throw(); + //! Get the network subsystem's minor version int getMinor() const throw(); + //@} + protected: // XBase overrides virtual CString getWhat() const throw(); @@ -36,6 +60,11 @@ private: int m_minor; }; +//! Network subsystem incomplete exception +/*! +Thrown when the network subsystem is missing an expected and required +function. +*/ class XNetworkFunctionUnavailable : public XNetwork { public: XNetworkFunctionUnavailable(const char* name) throw(); diff --git a/net/XSocket.cpp b/net/XSocket.cpp index 63f9fc03..d1c5f661 100644 --- a/net/XSocket.cpp +++ b/net/XSocket.cpp @@ -4,7 +4,7 @@ // XSocketAddress // -XSocketAddress::XSocketAddress(Error error, +XSocketAddress::XSocketAddress(EError error, const CString& hostname, UInt16 port) throw() : m_error(error), m_hostname(hostname), @@ -13,7 +13,7 @@ XSocketAddress::XSocketAddress(Error error, // do nothing } -XSocketAddress::Error +XSocketAddress::EError XSocketAddress::getError() const throw() { return m_error; diff --git a/net/XSocket.h b/net/XSocket.h index 354e57af..4adca77b 100644 --- a/net/XSocket.h +++ b/net/XSocket.h @@ -5,36 +5,58 @@ #include "CString.h" #include "BasicTypes.h" +//! Generic socket exception class XSocket : public XBase { }; +//! Socket bad address exception +/*! +Thrown when attempting to create an invalid network address. +*/ class XSocketAddress : public XSocket { public: - enum Error { kUnknown, kNotFound, kNoAddress, kBadPort }; + //! Failure codes + enum EError { + kUnknown, //!< Unknown error + kNotFound, //!< The hostname is unknown + kNoAddress, //!< The hostname is valid but has no IP address + kBadPort //!< The port is invalid + }; - XSocketAddress(Error, const CString& hostname, UInt16 port) throw(); + XSocketAddress(EError, const CString& hostname, UInt16 port) throw(); - // accessors + //! @name accessors + //@{ - virtual Error getError() const throw(); - virtual CString getHostname() const throw(); - virtual UInt16 getPort() const throw(); + //! Get the error code + EError getError() const throw(); + //! Get the hostname + CString getHostname() const throw(); + //! Get the port + UInt16 getPort() const throw(); + + //@} protected: // XBase overrides virtual CString getWhat() const throw(); private: - Error m_error; + EError m_error; CString m_hostname; UInt16 m_port; }; +//! Generic socket exception using \c errno class XSocketErrno : public XSocket, public MXErrno { public: XSocketErrno(); XSocketErrno(int); }; +//! Socket cannot bind address exception +/*! +Thrown when a socket cannot be bound to an address. +*/ class XSocketBind : public XSocketErrno { public: XSocketBind() { } @@ -45,12 +67,21 @@ protected: virtual CString getWhat() const throw(); }; +//! Socket address in use exception +/*! +Thrown when a socket cannot be bound to an address because the address +is already in use. +*/ class XSocketAddressInUse : public XSocketBind { public: XSocketAddressInUse() { } XSocketAddressInUse(int e) : XSocketBind(e) { } }; +//! Cannot connect socket exception +/*! +Thrown when a socket cannot connect to a remote endpoint. +*/ class XSocketConnect : public XSocketErrno { public: XSocketConnect() { } @@ -61,6 +92,10 @@ protected: virtual CString getWhat() const throw(); }; +//! Cannot create socket exception +/*! +Thrown when a socket cannot be created (by the operating system). +*/ class XSocketCreate : public XSocketErrno { public: XSocketCreate() { }