001: package org.apache.commons.net.ntp;
002:
003: /*
004: * Copyright 2001-2005 The Apache Software Foundation
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: import java.io.IOException;
020: import java.net.DatagramPacket;
021: import java.net.InetAddress;
022: import org.apache.commons.net.DatagramSocketClient;
023:
024: /***
025: * The NTPUDPClient class is a UDP implementation of a client for the
026: * Network Time Protocol (NTP) described in RFC 1305 as well as the
027: * Simple Network Time Protocol (SNTP) in RFC-2030. To use the class,
028: * merely open a local datagram socket with <a href="#open"> open </a>
029: * and call <a href="#getTime"> getTime </a> to retrieve the time. Then call
030: * <a href="org.apache.commons.net.DatagramSocketClient.html#close"> close </a>
031: * to close the connection properly.
032: * Successive calls to <a href="#getTime"> getTime </a> are permitted
033: * without re-establishing a connection. That is because UDP is a
034: * connectionless protocol and the Network Time Protocol is stateless.
035: *
036: * @author Jason Mathews, MITRE Corp
037: * @version $Revision: 165675 $ $Date: 2005-05-02 15:09:55 -0500 (Mon, 02 May 2005) $
038: ***/
039:
040: public final class NTPUDPClient extends DatagramSocketClient {
041: /*** The default NTP port. It is set to 123 according to RFC 1305. ***/
042: public static final int DEFAULT_PORT = 123;
043:
044: private int _version = NtpV3Packet.VERSION_3;
045:
046: /***
047: * Retrieves the time information from the specified server and port and
048: * returns it. The time is the number of miliiseconds since
049: * 00:00 (midnight) 1 January 1900 UTC, as specified by RFC 1305.
050: * This method reads the raw NTP packet and constructs a <i>TimeInfo</i>
051: * object that allows access to all the fields of the NTP message header.
052: * <p>
053: * @param host The address of the server.
054: * @param port The port of the service.
055: * @return The time value retrieved from the server.
056: * @exception IOException If an error occurs while retrieving the time.
057: ***/
058: public TimeInfo getTime(InetAddress host, int port)
059: throws IOException {
060: // if not connected then open to next available UDP port
061: if (!isOpen()) {
062: open();
063: }
064:
065: NtpV3Packet message = new NtpV3Impl();
066: message.setMode(NtpV3Packet.MODE_CLIENT);
067: message.setVersion(_version);
068: DatagramPacket sendPacket = message.getDatagramPacket();
069: sendPacket.setAddress(host);
070: sendPacket.setPort(port);
071:
072: NtpV3Packet recMessage = new NtpV3Impl();
073: DatagramPacket receivePacket = recMessage.getDatagramPacket();
074:
075: /*
076: * Must minimize the time between getting the current time,
077: * timestamping the packet, and sending it out which
078: * introduces an error in the delay time.
079: * No extraneous logging and initializations here !!!
080: */
081: TimeStamp now = TimeStamp.getCurrentTime();
082:
083: // Note that if you do not set the transmit time field then originating time
084: // in server response is all 0's which is "Thu Feb 07 01:28:16 EST 2036".
085: message.setTransmitTime(now);
086:
087: _socket_.send(sendPacket);
088: _socket_.receive(receivePacket);
089:
090: long returnTime = System.currentTimeMillis();
091: // create TimeInfo message container but don't pre-compute the details yet
092: TimeInfo info = new TimeInfo(recMessage, returnTime, false);
093:
094: return info;
095: }
096:
097: /***
098: * Retrieves the time information from the specified server on the
099: * default NTP port and returns it. The time is the number of miliiseconds
100: * since 00:00 (midnight) 1 January 1900 UTC, as specified by RFC 1305.
101: * This method reads the raw NTP packet and constructs a <i>TimeInfo</i>
102: * object that allows access to all the fields of the NTP message header.
103: * <p>
104: * @param host The address of the server.
105: * @return The time value retrieved from the server.
106: * @exception IOException If an error occurs while retrieving the time.
107: ***/
108: public TimeInfo getTime(InetAddress host) throws IOException {
109: return getTime(host, NtpV3Packet.NTP_PORT);
110: }
111:
112: /***
113: * Returns the NTP protocol version number that client sets on request packet
114: * that is sent to remote host (e.g. 3=NTP v3, 4=NTP v4, etc.)
115: *
116: * @return the NTP protocol version number that client sets on request packet.
117: * @see #setVersion(int)
118: ***/
119: public int getVersion() {
120: return _version;
121: }
122:
123: /***
124: * Sets the NTP protocol version number that client sets on request packet
125: * communicate with remote host.
126: *
127: * @param version the NTP protocol version number
128: ***/
129: public void setVersion(int version) {
130: _version = version;
131: }
132:
133: }
|