Skip to content

Instantly share code, notes, and snippets.

@jonathanws
Created March 23, 2013 18:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonathanws/5228795 to your computer and use it in GitHub Desktop.
Save jonathanws/5228795 to your computer and use it in GitHub Desktop.
Modified from http://support.ntp.org/bin/view/Support/JavaSntpClient Modified to allow user to enter the name of the ntp server (i used north-america.pool.ntp.org), send three requests and print average roundtrip times, and print the last packet's server request time.
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.text.DecimalFormat;
import java.util.Scanner;
/**
* NtpClient - an NTP client for Java. This program connects to an NTP server
* and prints the response to the console.
*
* The local clock offset calculation is implemented according to the SNTP
* algorithm specified in RFC 2030.
*
* Note that on windows platforms, the curent time-of-day timestamp is limited
* to an resolution of 10ms and adversely affects the accuracy of the results.
*
*
* This code is copyright (c) Adam Buckley 2004
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version. A HTML version of the GNU General Public License can be
* seen at http://www.gnu.org/licenses/gpl.html
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* @author Adam Buckley
*/
public class SntpClient {
// Could make a static field in NtpMessage.java, but this way we edit one file
private static double mAverageRoundTrip = 0.0;
private static String thirdRequest = "";
public static void main(String[] args) throws IOException {
String serverName;
// // Process command-line args
// if(args.length == 1)
// serverName = args[0];
// else {
// printUsage();
// return;
// }
// Allow the user to enter the name of the NTP Server
serverName = enterNtpServer();
//Send three requests to the server
for (int i = 0; i < 3; i++) {
// Send request
DatagramSocket socket = new DatagramSocket();
InetAddress address = InetAddress.getByName(serverName);
byte[] buf = new NtpMessage().toByteArray();
DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 123);
// Set the transmit timestamp *just* before sending the packet
// ToDo: Does this actually improve performance or not?
NtpMessage.encodeTimestamp(packet.getData(), 40,
(System.currentTimeMillis()/1000.0) + 2208988800.0);
socket.send(packet);
// Get response
System.out.println("------------------------------------------------");
System.out.println("NTP request sent, waiting for response...\n");
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
// Immediately record the incoming timestamp
double destinationTimestamp =
(System.currentTimeMillis()/1000.0) + 2208988800.0;
// Process response
NtpMessage msg = new NtpMessage(packet.getData());
// Corrected, according to RFC2030 errata
double roundTripDelay = (destinationTimestamp-msg.originateTimestamp) -
(msg.transmitTimestamp-msg.receiveTimestamp);
// Add to accumulating total
mAverageRoundTrip += roundTripDelay;
double localClockOffset =
((msg.receiveTimestamp - msg.originateTimestamp) +
(msg.transmitTimestamp - destinationTimestamp)) / 2;
// Display response
System.out.println("NTP server: " + serverName);
System.out.println(msg.toString());
System.out.println("Dest. timestamp: " +
NtpMessage.timestampToString(destinationTimestamp));
System.out.println("Round-trip delay: " +
new DecimalFormat("0.00").format(roundTripDelay*1000) + " ms");
System.out.println("Local clock offset: " +
new DecimalFormat("0.00").format(localClockOffset*1000) + " ms\n\n");
// If last time
if ( i == 2) {
thirdRequest = NtpMessage.timestampToString(msg.transmitTimestamp);
}
socket.close();
} // End loop
mAverageRoundTrip /= 3; // Take average
System.out.println("------------------------------------------------");
System.out.println("Average round trip: " + new DecimalFormat("0.00").format(mAverageRoundTrip * 1000));
System.out.print("Server received the 3rd request at: " + thirdRequest);
}
/**
* Prints usage
*/
static void printUsage() {
System.out.println(
"NtpClient - an NTP client for Java.\n" +
"\n" +
"This program connects to an NTP server and prints the response to the console.\n" +
"\n" +
"\n" +
"Usage: java NtpClient server\n" +
"\n" +
"\n" +
"This program is copyright (c) Adam Buckley 2004 and distributed under the terms\n" +
"of the GNU General Public License. This program is distributed in the hope\n" +
"that it will be useful, but WITHOUT ANY WARRANTY; without even the implied\n" +
"warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" +
"General Public License available at http://www.gnu.org/licenses/gpl.html for\n" +
"more details.");
}
private static String enterNtpServer() {
Scanner reader = new Scanner(System.in);
System.out.print("Enter name of NTP Server: ");
return reader.nextLine();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment