public boolean requestTime ( String host , int timeout ) { DatagramSocket socket = null ; try { socket = new DatagramSocket ( ) ; socket . setSoTimeout ( timeout ) ; InetAddress address = InetAddress . getByName ( host ) ; byte [ ] buffer = new byte [ NTP_PACKET_SIZE ] ; DatagramPacket request = new DatagramPacket ( buffer , buffer . length , address , NTP_PORT ) ; // set mode = 3 (client) and version = 3 // mode is in low 3 bits of first byte // version is in bits 3-5 of first byte buffer [ 0 ] = NTP_MODE_CLIENT | ( NTP_VERSION << 3 ) ; // get current time and write it to the request packet long requestTime = System . currentTimeMillis ( ) ; long requestTicks = SystemClock . elapsedRealtime ( ) ; writeTimeStamp ( buffer , TRANSMIT_TIME_OFFSET , requestTime ) ; socket . send ( request ) ; // read the response DatagramPacket response = new DatagramPacket ( buffer , buffer . length ) ; socket . receive ( response ) ; long responseTicks = SystemClock . elapsedRealtime ( ) ; long responseTime = requestTime + ( responseTicks - requestTicks ) ; // extract the results long originateTime = readTimeStamp ( buffer , ORIGINATE_TIME_OFFSET ) ; long receiveTime = readTimeStamp ( buffer , RECEIVE_TIME_OFFSET ) ; long transmitTime = readTimeStamp ( buffer , TRANSMIT_TIME_OFFSET ) ; long roundTripTime = responseTicks - requestTicks - ( transmitTime - receiveTime ) ; // receiveTime = originateTime + transit + skew // responseTime = transmitTime + transit - skew // clockOffset = ((receiveTime - originateTime) + (transmitTime - responseTime))/2 // = ((originateTime + transit + skew - originateTime) + // (transmitTime - (transmitTime + transit - skew)))/2 // = ((transit + skew) + (transmitTime - transmitTime - transit + skew))/2 // = (transit + skew - transit + skew)/2 // = (2 * skew)/2 = skew mClockOffset = ( ( receiveTime - originateTime ) + ( transmitTime - responseTime ) ) / 2 ; // if (false) Log.d(TAG, "round trip: " + roundTripTime + " ms"); // if (false) Log.d(TAG, "clock offset: " + clockOffset + " ms"); // save our results - use the times on this side of the network latency // (response rather than request time) mNtpTime = responseTime + mClockOffset ; mNtpTimeReference = responseTicks ; mRoundTripTime = roundTripTime ; } catch ( Exception e ) { return false ; } finally { if ( socket != null ) { socket . close ( ) ; } } return true ; }
Sends an SNTP request to the given host and processes the response .