NAME

DwProtocolClient -- Base class for all protocol clients

SYNOPSIS

class DW_EXPORT DwProtocolClient {

public:

    enum Failure {
        kFailNoFailure      = 0, // No failure
        kFailNoWinsock      = 1, // A usable Winsock DLL could not be found
        kFailNetDown        = 2, // The network is down
        kFailHostNotFound   = 3, // The server was not found
        kFailConnReset      = 4, // The connection was reset
        kFailNetUnreachable = 5, // The network is unreachable
        kFailTimedOut       = 6, // Timed out while waiting for an operation
                                 // to complete
        kFailConnDropped    = 7,
        kFailConnRefused    = 8,
        kFailNoResources    = 9
    };

    enum Error {
        kErrNoError = 0,
        kErrUnknownError = 0x4000,
        kErrBadParameter = 0x4001,
        kErrBadUsage     = 0x4002,
        kErrNoWinsock    = 0x4003,  // Win32
        kErrHostNotFound = 0x5000,  // UNIX
        kErrTryAgain     = 0x5001,  // UNIX
        kErrNoRecovery   = 0x5002,  // UNIX
        kErrNoData       = 0x5003,  // UNIX
        kErrNoAddress    = 0x5004,  // UNIX
    };

protected:

    DwProtocolClient();

public:

    virtual ~DwProtocolClient();
    virtual int Open(const char* aServer, DwUint16 aPort);
    DwBool IsOpen() const;
    int Close();
    int SetReceiveTimeout(int aSecs);
    int LastCommand() const;
    int LastFailure() const;
    const char* LastFailureStr() const;
    int LastError() const;
    const char* LastErrorStr() const;

protected:

    enum {
        kWSAStartup=1,  // Win32
        kgethostbyname,
        tdesocket,
        ksetsockopt,
        kconnect,
        ksend,
        krecv,
        kclose,         // UNIX
        kclosesocket,   // Win32
        kselect
    };
    DwBool      mIsDllOpen;
    DwBool      mIsOpen;
    SOCKET      mSocket;
    DwUint16    mPort;
    char*       mServerName;
    int         mReceiveTimeout;
    int         mLastCommand;
    int         mFailureCode;
    const char* mFailureStr;
    int         mErrorCode;
    const char* mErrorStr;
    virtual void HandleError(int aErrorCode, int aSystemCall);
    int PSend(const char* aBuf, int aBufLen);
    int PReceive(char* aBuf, int aBufSize);
};

DESCRIPTION

DwProtocolClient is the base class for other classes that implement specific protocols, such as SMTP, POP, and NNTP. DwProtocolClient serves two purposes. First, It combines operations common to all its derived classes, such as opening a TCP connection to the server. Second, it provides a platform-independent interface to the network services required by its subclasses.

There are two separate implementations of DwProtocolClient: one for Berkeley sockets under UNIX, and one for Winsock under Win32. The interface is the same for both implementations, thus providing platform independence.

There are two platform-specific details that you should be aware of. First, if you are writing a UNIX program, you should be sure to handle the SIGPIPE signal. This signal is raised when a program tries to write to a TCP connection that was shutdown by the remote host. The default action for this signal is to terminate the program. To prevent this from happening in your program, you should either catch the signal or tell the operating system to ignore it. Second, if you are writing a Win32 application for Windows NT or Windows95, you should be aware of the fact that the constructor calls the Winsock function WSAStartup() to initialize the Winsock DLL. (The destructor calls WSACleanup().) Because it is possible for WSAStartup() to fail, it is also possible that the constructor may fail. To verify that the constructor has succeeded, call the member function LastError() and check that it returns zero.

To open a connection to a server, call Open() with the server name and TCP port number as arguments. Open() is declared virtual; derived classes may override this member function. Open() may fail, so you should check the return value to verify that it succeeded. To close the connection, call Close(). To check if a connection is open, call IsOpen(). IsOpen() returns a value that indicates whether or not a call to Open() was successful; it will not detect failure in the network or a close operation by the remote host.

DwProtocolClient sets a timeout on receive operations on the TCP connection. The default value of the timeout period is 90 seconds. To change the default value, call SetReceiveTimeout() and pass the new value as an argument.

Whenever DwProtocolClient cannot complete an operation, it is because an error has occurred. Most member functions indicate that an error has occurred via their return values. For most member functions, a return value of -1 indicates an error. To get the specific error that has occurred, call LastError(), which returns either the system error code or a MIME++ defined error code. To get a text string that describes the error, call LastErrorStr().

Some errors are also considered "failures." A failure occurs when an operation cannot be completed because of conditions external to the program. For example, a failure occurs when the network is down or when an application's user enters bad input. Errors that occur because of programmer error are not considered failures. If an error occurs, you should call LastError() to determine the error, but you should also call LastFailure() to determine if a failure occurred. In interactive applications, failures should always be reported to the application's user. To get a text string that describes a failure, call LastFailureStr().

It is possible to translate the error and failure message strings to a language other than English. To do this, you may override the virtual function HandleError().

Public Member Functions

virtual ~DwProtocolClient()

Frees the resources used by this object. In a Win32 environment, the destructor calls WSACleanup().

virtual int Open(const char* aServer, DwUint16 aPort)

Opens a TCP connection to the server aServer at port aPort. aServer may be either a host name, such as "smtp.acme.com" or an IP number in dotted decimal format, such as "147.81.64.59". If the connection attempt succeeds, Open() returns 0; othewise, it returns -1. To determine what error occurred when the connection attempt fails, call the member function LastError(). To determine if a failure also occurred, call the member function LastFailure().

DwBool IsOpen() const

Returns true value if a connection to the server is open. IsOpen() will return a true value if a call to Open() was successful; it will not detect failure in the network or a close operation by the remote host.

int Close()

Closes the connection to the server. Returns 0 if successful, or returns -1 if unsuccessful.

int SetReceiveTimeout(int aSecs)

Changes the default timeout for receive operations on the socket to aSecs seconds. The default value is 90 seconds.

int LastCommand() const

Returns an enumerated value indicating the last command sent to the server. Enumerated values are defined in subclasses of DwProtocolClient.

int LastFailure() const

Returns an enumerated value indicating what failure last occurred.

const char* LastFailureStr() const

Returns a failure message string associated with the failure code returned by LastFailure().

int LastError() const

Returns an error code for the last error that occurred. Normally, the error code returned is an error code returned by a system call; DwProtocolClient does no translation of error codes returned by system calls. In some cases, an error code defined by MIME++ may returned to indicate improper use of the DwProtocolClient class.

const char* LastErrorStr() const

Returns an error message string associated with the error code returned by LastError().

Protected Member Functions

DwProtocolClient()

Initializes the DwProtocolClient object. In a Win32 environment, this constructor calls WSAStartup() to initialize the Winsock DLL. To verify that the DLL was initialized successfully, call the member function LastError() and verify that it returns zero.

virtual void HandleError(int aErrorCode, int aSystemCall)

Interprets error codes. aErrorCode is an error code, which may be a system error code, or an error code defined by DwProtocolClient. aSystemCall is an enumerated value defined by DwProtocolClient that indicates the last system call made, which should be the system call that set the error code. HandleError() sets values for mErrorStr, mFailureCode, and mFailureStr.

int PSend(const char* aBuf, int aBufLen)

Sends aBufLen characters from the buffer aBuf. Returns the number of characters sent. If the number of characters sent is less than the number of characters specified in aBufLen, the caller should call LastError() to determine what, if any, error occurred. To determine if a failure also occurred, call the member function LastFailure().

int PReceive(char* aBuf, int aBufSize)

Receives up to aBufSize characters into the buffer aBuf. Returns the number of characters received. If zero is returned, the caller should call the member function LastError() to determine what, if any, error occurred. To determine if a failure also occurred, call the member function LastFailure().