001    package railo.runtime.net.ntp;
002    
003    import java.io.IOException;
004    import java.net.DatagramPacket;
005    import java.net.DatagramSocket;
006    import java.net.InetAddress;
007    
008    
009    
010    /**
011     * NtpClient - an NTP client for Java.  This program connects to an NTP server
012     */
013    public final class NtpClient    {
014            
015            
016            private String serverName;
017            
018    
019            /**
020             * default constructor of the class
021             * @param serverName
022             */
023            public NtpClient(String serverName) {
024                    this.serverName=serverName;
025            }
026            
027    
028            
029            /**
030             * returns the offest from the ntp server to local system
031             * @return
032             * @throws IOException
033             */
034            public long getOffset() throws IOException {
035                    /// Send request
036                    DatagramSocket socket = new DatagramSocket();
037                    socket.setSoTimeout(10000);
038                    InetAddress address = InetAddress.getByName(serverName);
039                    byte[] buf = new NtpMessage().toByteArray();
040                    DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 123);
041                    
042                    // Set the transmit timestamp *just* before sending the packet
043                    NtpMessage.encodeTimestamp(packet.getData(), 40, (System.currentTimeMillis()/1000.0) + 2208988800.0);
044                    
045                    socket.send(packet);
046                    
047                    // Get response
048                    packet = new DatagramPacket(buf, buf.length);
049                    socket.receive(packet);
050                    
051                    // Immediately record the incoming timestamp
052                    double destinationTimestamp = (System.currentTimeMillis()/1000.0) + 2208988800.0;
053                    
054                    
055                    // Process response
056                    NtpMessage msg = new NtpMessage(packet.getData());
057                    //double roundTripDelay = (destinationTimestamp-msg.originateTimestamp) - (msg.receiveTimestamp-msg.transmitTimestamp);
058                    double localClockOffset = ((msg.receiveTimestamp - msg.originateTimestamp) + (msg.transmitTimestamp - destinationTimestamp)) / 2;
059                    
060                    return (long) (localClockOffset*1000);
061            }
062            
063            /**
064             * returns the current time from ntp server in ms from 1970
065             * @return
066             * @throws IOException
067             */
068            public long currentTimeMillis() throws IOException {
069                    return System.currentTimeMillis()+getOffset();
070            }
071            
072            /*
073            public static void main(String[] args) throws IOException{
074                    NtpClient ntp=new NtpClient("time.nist.gov");
075                    
076            }
077            public static void main(String[] args) throws IOException
078            {
079                    
080                    String serverName="time.nist.gov";
081                    
082                    
083                    
084                    
085                    /// Send request
086                    DatagramSocket socket = new DatagramSocket();
087                    InetAddress address = InetAddress.getByName(serverName);
088                    byte[] buf = new NtpMessage().toByteArray();
089                    DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 123);
090                    
091                    // Set the transmit timestamp *just* before sending the packet
092                    // ToDo: Does this improve performance or not?
093                    NtpMessage.encodeTimestamp(packet.getData(), 40, (System.currentTimeMillis()/1000.0) + 2208988800.0);
094                    
095                    socket.send(packet);
096                    
097                    // Get response
098                    packet = new DatagramPacket(buf, buf.length);
099                    socket.receive(packet);
100                    
101                    // Immediately record the incoming timestamp
102                    double destinationTimestamp = (System.currentTimeMillis()/1000.0) + 2208988800.0;
103                    
104                    
105                    // Process response
106                    NtpMessage msg = new NtpMessage(packet.getData());
107                    double roundTripDelay = (destinationTimestamp-msg.originateTimestamp) - (msg.receiveTimestamp-msg.transmitTimestamp);
108                    double localClockOffset = ((msg.receiveTimestamp - msg.originateTimestamp) + (msg.transmitTimestamp - destinationTimestamp)) / 2;
109                    
110                    
111                    // Display response
112                    
113                    socket.close();
114            }*/
115            
116            
117    }