alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Commons Net example source code file (TimeInfo.java)

This example Commons Net source code file (TimeInfo.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Commons Net tags/keywords

arraylist, destrcvtime, error, error, list, list, long, long, ntpv3packet, origtime, timeinfo, timeinfo, timestamp, util, warning

The Commons Net TimeInfo.java source code

package org.apache.commons.net.ntp;
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


import java.util.ArrayList;
import java.util.List;

/**
 * Wrapper class to network time packet messages (NTP, etc) that computes
 * related timing info and stats.
 *
 * @author Jason Mathews, MITRE Corp
 *
 * @version $Revision: 929649 $ $Date: 2010-03-31 19:12:07 +0100 (Wed, 31 Mar 2010) $
 */
public class TimeInfo {

    private final NtpV3Packet _message;
    private List<String> _comments;
    private Long _delay;
    private Long _offset;

    /**
     * time at which time message packet was received by local machine
     */
    private final long _returnTime;

    /**
     * flag indicating that the TimeInfo details was processed and delay/offset were computed
     */
    private boolean _detailsComputed;

    /**
     * Create TimeInfo object with raw packet message and destination time received.
     *
     * @param message NTP message packet
     * @param returnTime  destination receive time
     * @throws IllegalArgumentException if message is null
     */
    public TimeInfo(NtpV3Packet message, long returnTime) {
        this(message, returnTime, null, true);
    }

    /**
     * Create TimeInfo object with raw packet message and destination time received.
     *
     * @param message NTP message packet
     * @param returnTime  destination receive time
     * @param comments List of errors/warnings identified during processing
     * @throws IllegalArgumentException if message is null
     */
    public TimeInfo(NtpV3Packet message, long returnTime, List<String> comments)
    {
            this(message, returnTime, comments, true);
    }

    /**
     * Create TimeInfo object with raw packet message and destination time received.
     * Auto-computes details if computeDetails flag set otherwise this is delayed
     * until computeDetails() is called. Delayed computation is for fast
     * intialization when sub-millisecond timing is needed.
     *
     * @param msgPacket NTP message packet
     * @param returnTime  destination receive time
     * @param doComputeDetails  flag to pre-compute delay/offset values
     * @throws IllegalArgumentException if message is null
     */
    public TimeInfo(NtpV3Packet msgPacket, long returnTime, boolean doComputeDetails)
    {
            this(msgPacket, returnTime, null, doComputeDetails);
    }

    /**
     * Create TimeInfo object with raw packet message and destination time received.
     * Auto-computes details if computeDetails flag set otherwise this is delayed
     * until computeDetails() is called. Delayed computation is for fast
     * intialization when sub-millisecond timing is needed.
     *
     * @param message NTP message packet
     * @param returnTime  destination receive time
     * @param comments  list of comments used to store errors/warnings with message
     * @param doComputeDetails  flag to pre-compute delay/offset values
     * @throws IllegalArgumentException if message is null
     */
    public TimeInfo(NtpV3Packet message, long returnTime, List<String> comments,
                   boolean doComputeDetails)
    {
        if (message == null)
            throw new IllegalArgumentException("message cannot be null");
        this._returnTime = returnTime;
        this._message = message;
        this._comments = comments;
        if (doComputeDetails)
            computeDetails();
    }

    /**
     * Add comment (error/warning) to list of comments associated
     * with processing of NTP parameters. If comment list not create
     * then one will be created.
     *
     * @param comment
     */
    public void addComment(String comment)
    {
        if (_comments == null) {
            _comments = new ArrayList<String>();
        }
        _comments.add(comment);
    }

    /**
     * Compute and validate details of the NTP message packet. Computed
     * fields include the offset and delay.
     */
    public void computeDetails()
    {
        if (_detailsComputed) {
            return; // details already computed - do nothing
        }
        _detailsComputed = true;
        if (_comments == null) {
            _comments = new ArrayList<String>();
        }

        TimeStamp origNtpTime = _message.getOriginateTimeStamp();
        long origTime = origNtpTime.getTime();

        // Receive Time is time request received by server (t2)
        TimeStamp rcvNtpTime = _message.getReceiveTimeStamp();
        long rcvTime = rcvNtpTime.getTime();

        // Transmit time is time reply sent by server (t3)
        TimeStamp xmitNtpTime = _message.getTransmitTimeStamp();
        long xmitTime = xmitNtpTime.getTime();

        /*
         * Round-trip network delay and local clock offset (or time drift) is calculated
         * according to this standard NTP equation:
         *
         * LocalClockOffset = ((ReceiveTimestamp - OriginateTimestamp) +
         *                     (TransmitTimestamp - DestinationTimestamp)) / 2
         *
         * equations from RFC-1305 (NTPv3)
         *      roundtrip delay = (t4 - t1) - (t3 - t2)
         *      local clock offset = ((t2 - t1) + (t3 - t4)) / 2
         *
         * It takes into account network delays and assumes that they are symmetrical.
         *
         * Note the typo in SNTP RFCs 1769/2030 which state that the delay
         * is (T4 - T1) - (T2 - T3) with the "T2" and "T3" switched.
         */
        if (origNtpTime.ntpValue() == 0)
        {
            // without originate time cannot determine when packet went out
            // might be via a broadcast NTP packet...
            if (xmitNtpTime.ntpValue() != 0)
            {
                _offset = Long.valueOf(xmitTime - _returnTime);
                _comments.add("Error: zero orig time -- cannot compute delay");
            } else
                _comments.add("Error: zero orig time -- cannot compute delay/offset");
        } else if (rcvNtpTime.ntpValue() == 0 || xmitNtpTime.ntpValue() == 0)
        {
            _comments.add("Warning: zero rcvNtpTime or xmitNtpTime");
            // assert destTime >= origTime since network delay cannot be negative
            if (origTime > _returnTime)
                _comments.add("Error: OrigTime > DestRcvTime");
            else
            {
                // without receive or xmit time cannot figure out processing time
                // so delay is simply the network travel time
                _delay = Long.valueOf(_returnTime - origTime);
            }
            // TODO: is offset still valid if rcvNtpTime=0 || xmitNtpTime=0 ???
            // Could always hash origNtpTime (sendTime) but if host doesn't set it
            // then it's an malformed ntp host anyway and we don't care?
            // If server is in broadcast mode then we never send out a query in first place...
            if (rcvNtpTime.ntpValue() != 0)
            {
                // xmitTime is 0 just use rcv time
                _offset = Long.valueOf(rcvTime - origTime);
            } else if (xmitNtpTime.ntpValue() != 0)
            {
                // rcvTime is 0 just use xmitTime time
                _offset = Long.valueOf(xmitTime - _returnTime);
            }
        } else
        {
             long delayValue = _returnTime - origTime;
             // assert xmitTime >= rcvTime: difference typically < 1ms
             if (xmitTime < rcvTime)
             {
                 // server cannot send out a packet before receiving it...
                 _comments.add("Error: xmitTime < rcvTime"); // time-travel not allowed
             } else
             {
                 // subtract processing time from round-trip network delay
                 long delta = xmitTime - rcvTime;
                 // in normal cases the processing delta is less than
                 // the total roundtrip network travel time.
                 if (delta <= delayValue)
                 {
                     delayValue -= delta; // delay = (t4 - t1) - (t3 - t2)
                 } else
                 {
                     // if delta - delayValue == 1 ms then it's a round-off error
                     // e.g. delay=3ms, processing=4ms
                     if (delta - delayValue == 1)
                     {
                         // delayValue == 0 -> local clock saw no tick change but destination clock did
                         if (delayValue != 0)
                         {
                             _comments.add("Info: processing time > total network time by 1 ms -> assume zero delay");
                             delayValue = 0;
                         }
                     } else
                         _comments.add("Warning: processing time > total network time");
                 }
             }
             _delay = Long.valueOf(delayValue);
            if (origTime > _returnTime) // assert destTime >= origTime
                _comments.add("Error: OrigTime > DestRcvTime");

            _offset = Long.valueOf(((rcvTime - origTime) + (xmitTime - _returnTime)) / 2);
        }
    }

    /**
     * Return list of comments (if any) during processing of NTP packet.
     *
     * @return List or null if not yet computed
     */
    public List<String> getComments()
    {
        return _comments;
    }

    /**
     * Get round-trip network delay. If null then could not compute the delay.
     *
     * @return Long or null if delay not available.
     */
    public Long getDelay()
    {
        return _delay;
    }

    /**
     * Get clock offset needed to adjust local clock to match remote clock. If null then could not
     * compute the offset.
     *
     * @return Long or null if offset not available.
     */
    public Long getOffset()
    {
        return _offset;
    }

    /**
     * Returns NTP message packet.
     *
     * @return NTP message packet.
     */
    public NtpV3Packet getMessage()
    {
        return _message;
    }

    /**
     * Returns time at which time message packet was received by local machine.
     *
     * @return packet return time.
     */
    public long getReturnTime()
    {
        return _returnTime;
    }

}

Other Commons Net examples (source code examples)

Here is a short list of links related to this Commons Net TimeInfo.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.