Created
March 23, 2013 18:11
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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