Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

CSNTPClient - An SNTP Implementation

0.00/5 (No votes)
7 Apr 2000 1  
A collection of freeware MFC classes to encapsulate the SNTP protocol.
  • Download source files - 17 Kb
  • Welcome to CSNTPClient, a collection of freeware MFC classes to encapsulate the SNTP protocol.


    Features
    Usage
    History
    API Reference
    Planned Enhancements
    Contacting the Author


    Features

    • Simple and clean C++ interface.
    • The interface provided is synchronous which provides an easier programming model than using asynchronous sockets.
    • Raw sockets are used instead of MFC sockets. This means that the code will work in a console application without any problems.
    • A configurable timeout for the connection can be set through the class API.
    • The classes are fully Unicode compliant and include Unicode built options in the workspace file.


    Usage

    • To use the class in your code simply include sntp.cpp in your project and #include sntp.h in which ever of your modules needs to make calls to the class.
    • Your code will need to include MFC either statically or dynamically.
    • You will need to have a functioning winsock stack installed as the code links to winsock.dll.
    • You will also need to have winsock.h or afxsock.h and afxpriv.h in your precompiled header. The code should also work in a multithreaded application, although it has not be explicitly tested in this scenario.


    History

    V1.0 (8th August 1998)
    • Initial public release.

    V1.01 (16th November 1998)

    • m_nOriginateTime was getting set incorrectly in the SNTP response. Has now been fixed.
    • GetLastError() now works when a timeout occurs.


    API Reference

    The API consists of the the classes:

    CNtpTime:

    This is an encapsulation of a time instance as used in the SNTP protocol. This consists of a 64 bit unsigned integer with the top 32 bits containing the number of seconds since 1st January 1900 and the lower 32 bits contain the fraction of seconds.


    CNtpTime
    operator=
    operator-
    operator+
    operator SYSTEMTIME
    operator CNtpTimePacket
    operator unsigned __int64
    Seconds
    Fraction
    GetCurrentTime
    MsToNtpFraction
    NtpFractionToMs
    NtpFractionToSecond


    NtpServerResponse

    This is a simple encapsulation of the information retrieved from the SNTP server. It contains:

    m_nLeapIndicator
    m_nStratum
    m_OriginateTime
    m_ReceiveTime
    m_TransmitTime
    m_DestinationTime
    m_RoundTripDelay
    m_LocalClockOffset


    CSNTPClient

    The actual class to call to perform a time lookup is CSNTPClient and it consists of:

    CSNTPClient
    GetServerTime
    GetTimeout
    SetTimeout
    SetClientTime


    CNtpTime::CNtpTime

    CNtpTime();
    CNtpTime(const CNtpTime& time);
    CNtpTime(CNtpTimePacket& packet);
    CNtpTime(const SYSTEMTIME& st);

    Parameters:

    • time -- Another CNtpTime instance.
    • packet -- An CNtpTimePacket instance. This is a simple struct representing the data as sent over the wire.
    • st -- A Win32 SDK SYSTEMTIME instance.

    Remarks:
    Standard C++ constructor.


    CNtpTime::operator=

    CNtpTime& operator=(const CNtpTime& time);

    Remarks:
    Standard operator= for the class.


    CNtpTime::operator-

    double operator-(const CNtpTime& time) const;

    Remarks:
    Standard operator- for the class.


    CNtpTime::operator+

    CNtpTime operator+(const double& timespan) const;

    Remarks:
    Standard operator+ for the class.


    CNtpTime::operator SYSTEMTIME

    operator SYSTEMTIME() const;

    Remarks:
    Returns a SDK SYSTEMTIME representation of the Ntp time.


    CNtpTime::operator CNtpTimePacket

    operator CNtpTimePacket() const;

    Remarks:
    Returns a CNtpTimePacket representation of an Ntp time. This structure is the actual value which gets transmitted to the SNTP server.


    CNtpTime::operator unsigned __int64

    operator unsigned __int64() const;

    Remarks:
    Returns an unsigned int64 representation of the Ntp time.


    CNtpTime::Seconds

    DWORD Seconds() const;

    Remarks:
    Returns the total number of seconds which this Ntp time represents.


    CNtpTime::Fraction

    DWORD Fraction() const;

    Remarks:
    Returns the fractional part of seconds which this Ntp time represents.


    CNtpTime::GetCurrentTime

    static CNtpTime GetCurrentTime();

    Remarks:
    Constructs an NtpTime instance which represents the current UTC time of the machine.


    CNtpTime::MsToNtpFraction

    static DWORD MsToNtpFraction(WORD wMilliSeconds);

    Remarks:
    Converts a count of milliseconds to an Ntp fractional.


    CNtpTime::NtpFractionToMs

    static WORD NtpFractionToMs(DWORD dwFraction);

    Remarks:
    Converts an Ntp fractional to a count of milliseconds.


    CNtpTime::NtpFractionToSecond

    static double NtpFractionToSecond(DWORD dwFraction);

    Remarks:
    Converts an Ntp fractional to a fraction of a second as a floating point value.


    CNtpTime::m_nLeapIndicator

    int m_nLeapIndicator;

    Remarks:
    This value will contain one of the following values:

    • 0: no warning
    • 1: last minute in day has 61 seconds
    • 2: last minute has 59 seconds
    • 3: clock not synchronized


    CNtpTime::m_nStratum

    int m_nStratum;

    Remarks:
    This value will contain the stratum level of the server. It will be one of the following values:

    • 0: unspecified or unavailable
    • 1: primary reference (e.g., radio clock)
    • 2-15: secondary reference (via NTP or SNTP)
    • 16-255: reserved


    CNtpTime::m_nOriginateTime

    CNtpTime m_OriginateTime;

    Remarks:
    This is the client time when the request was sent from the client to the SNTP server.


    CNtpTime::m_ReceiveTime

    CNtpTime m_ReceiveTime;

    Remarks:
    This is the server time when the request was received by the SNTP server from the client.


    CNtpTime::m_TransmitTime

    CNtpTime m_TransmitTime;

    Remarks:
    This is the server time when the server sent the request back to the client.


    CNtpTime::m_DestinationTime

    CNtpTime m_DestinationTime;

    Remarks:
    This is the client time when the reply was received by the client.


    CNtpTime::m_RoundTripDelay

    double m_RoundTripDelay;

    Remarks:
    This is the round trip time in seconds for the Ntp request. It is calculated as:
    m_RoundTripDelay = (m_DestinationTime - m_OriginateTime) - (m_ReceiveTime - m_TransmitTime);


    CNtpTime::m_LocalClockOffset

    double m_LocalClockOffset;

    Remarks:
    This is the local clock offset relative to the server. This is calculated as:
    LocalClockOffset = ((m_ReceiveTime - m_OriginateTime) + (m_TransmitTime - m_DestinationTime)) / 2;

    This value can then be used to set the local time by a simple call as follows:
    CNtpTime newSynchronizedTime(CNtpTime::GetCurrentTime() + m_LocalClockOffset);


    CSNTPClient::CSNTPClient

    CSNTPClient();

    Remarks:
    Standard C++ constructor which initializes the timeout to a default value of 5 seconds.


    CSNTPClient::GetServerTime

    BOOL GetServerTime(LPCTSTR pszHostName, NtpServerResponse& response, int nPort = 123);

    Return Value:
    If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError().

    Parameters:

    • pszHostName -- The network address of the SNTP server to connect to: a machine name such as "ntp.maths.tcd.ie", or a dotted number such as "128.56.22.8" will both work.
    • response -- Upon a successful call to this function, this will contain all the information relating to the SNTP server.
    • nPort -- This is the port number of which to make a SNTP request. The default value is 123.

    Remarks:
    This performs the actual SNTP query and returns the relevant information back in the response structure. You are then free to decide if you want to set the local time using the values retrieved.


    CSNTPClient::GetTimeout

    DWORD GetTimeout() const;

    Return Value:
    The current timeout to use for socket calls which will block while doing the SNTP query.


    CSNTPClient::SetTimeout

    void SetTimeout(DWORD dwTimeout);

    Parameters:

    • dwTimeout -- The new timeout to use for socket calls which will block while doing the SNTP query.


    CSNTPClient::SetClientTime

    BOOL SetClientTime(const CNtpTime& NewTime);

    Return Value:
    If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError().

    Parameters:

    • NewTime -- An Ntp time representation of the time to be use to set the client time.

    Remarks:
    Given a time, this function will set the client system time. Internally it looks after setting privileges which is required on NT because of its security mode.



    Planned Enhancements

    • If you have any other suggested improvements, please let me know so that I can incorporate them into the next release.


    Contacting the Author

    PJ Naughter
    Email: pjn@indigo.ie
    Web: http://www.naughter.com/a>
    16th November 1998


    License