iOS Question Timeserver (solved)

Discussion in 'iOS Questions' started by Filippo, Jun 8, 2015.

  1. Filippo

    Filippo Expert Licensed User

    Hi,

    I can query the time from a time server and other not, someone know why?
    Code:
    Sub GetAtomtime
        Socket1.Initialize(
    "Socket1")
       
        
    'All Server work
        Socket1.Connect("time-a.nist.gov"1310000)
    '    Socket1.Connect("time.nist.gov", 13, 10000)
    '    Socket1.Connect("time-a.timefreq.bldrdoc.gov", 13, 10000)
    '    Socket1.Connect("ntp-nist.ldsbc.edu", 13, 10000)
    '    Socket1.Connect("nist-time-server.eoni.com", 13, 10000)

        
    'All server not work
    '    Socket1.Connect("de.pool.ntp.org", 13, 10000)
    '    Socket1.Connect("it.pool.ntp.org", 13, 10000)
    '    Socket1.Connect("uk.pool.ntp.org", 13, 10000)
    End Sub
     

    Attached Files:

  2. Erel

    Erel Administrator Staff Member Licensed User

    What happens when you try to connect to the ones that do not work?
     
  3. Filippo

    Filippo Expert Licensed User

    Nothing happens.
    This event will not fire.
    Code:
    Sub Socket1_Connected (Successful As Boolean)
        
    Log("Successful=" & Successful)
        
    If Successful Then
            AStreams.Initialize(Socket1.InputStream, Socket1.OutputStream, 
    "AStreams")
        
    Else
            Socket1.Close
        
    End If
    End Sub
     
  4. Erel

    Erel Administrator Staff Member Licensed User

    I tried it with: de.pool.ntp.org

    The event is raised with Successful = false (the same when tested with B4J). Make sure that the iNetwork version is 1.10.
     
  5. Filippo

    Filippo Expert Licensed User

    But why bring "Successful = false"?
    With the Library "SPSntp" it works without problems, what's different?
     
  6. Erel

    Erel Administrator Staff Member Licensed User

    Are you sure that it listens on this port to TCP connections?
     
  7. Filippo

    Filippo Expert Licensed User

    I tried also with port 123 (see java-class), unfortunately without success.
    Code:
    package anywheresoftware.b4a.specci48.spsntp;

    import android.os.SystemClock;
    import android.util.Log;
    import anywheresoftware.b4a.BA;
    import anywheresoftware.b4a.BA.ActivityObject;
    import anywheresoftware.b4a.BA.ShortName;
    import anywheresoftware.b4a.BA.Version;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;

    @BA.ActivityObject
    @BA.ShortName(
    "SPSntp")
    @BA.Version(
    1.03F)
    public class SPSntp
    {
      
    private static String mNtpServerName = "0.us.pool.ntp.org";

      
    private static int mTimeOut = 30000;
      
    private static long mNtpTime;
      
    private static long mNtpTimeReference;
      
    private static long mRoundTripTime;

      
    private static class SntpClient
      {
        
    private static final String TAG = "SntpClient";
        
    private static final int ORIGINATE_TIME_OFFSET = 24;
        
    private static final int RECEIVE_TIME_OFFSET = 32;
        
    private static final int TRANSMIT_TIME_OFFSET = 40;
        
    private static final int NTP_PACKET_SIZE = 48;
        
    private static final int NTP_PORT = 123;
        
    private static final int NTP_MODE_CLIENT = 3;
        
    private static final int NTP_VERSION = 3;
        
    private static final long OFFSET_1900_TO_1970 = 2208988800L;

        
    public boolean requestTime(String host, int timeout)
        {
          
    try
          {
            DatagramSocket 
    socket = new DatagramSocket();
            
    socket.setSoTimeout(timeout);
            InetAddress 
    address = InetAddress.getByName(host);
            byte[] buffer = new byte[
    48];
            DatagramPacket request = new DatagramPacket(buffer, buffer.length, 
    address123);

            buffer[
    0] = 27;

            long requestTime = System.currentTimeMillis();
            long requestTicks = SystemClock.elapsedRealtime();
            writeTimeStamp(buffer, 
    40, requestTime);

            
    socket.send(request);

            DatagramPacket response = new DatagramPacket(buffer, buffer.length);
            
    socket.receive(response);
            long responseTicks = SystemClock.elapsedRealtime();
            long responseTime = requestTime + responseTicks - requestTicks;
            
    socket.close();

            long originateTime = readTimeStamp(buffer, 
    24);
            long receiveTime = readTimeStamp(buffer, 
    32);
            long transmitTime = readTimeStamp(buffer, 
    40);
            long roundTripTime = responseTicks - requestTicks - (transmitTime - receiveTime);

            long clockOffset = (receiveTime - originateTime + transmitTime - responseTime) / 2L;

            SPSntp.mNtpTime = responseTime + clockOffset;
            SPSntp.mNtpTimeReference = responseTicks;
            SPSntp.mRoundTripTime = roundTripTime;
          
    }
          catch (Exception e) {
            Log.d("SntpClient", "request time failed: " + e);

            return false;
          }

          return true;
        }

        private long read32(byte[] buffer, int offset)
        {
          byte b0 = buffer[offset];
          byte b1 = buffer[(offset + 1)];
          byte b2 = buffer[(offset + 2)];
          byte b3 = buffer[(offset + 3)];

          int i0 = (b0 & 0x80) == 128 ? (b0 & 0x7F) + 128 : b0;
          int i1 = (b1 & 0x80) == 128 ? (b1 & 0x7F) + 128 : b1;
          int i2 = (b2 & 0x80) == 128 ? (b2 & 0x7F) + 128 : b2;
          int i3 = (b3 & 0x80) == 128 ? (b3 & 0x7F) + 128 : b3;

          return (i0 << 24) + (i1 << 16) + (i2 << 8) + i3;
        }

        public long readTimeStamp(byte[] buffer, int offset)
        {
          long seconds = read32(buffer, offset);
          long fraction = read32(buffer, offset + 4);
          return (seconds - 2208988800L) * 1000L + fraction * 1000L / 4294967296L;
        }

        private void writeTimeStamp(byte[] buffer, int offset, long time)
        {
          long seconds = time / 1000L;
          long milliseconds = time - seconds * 1000L;
          seconds += 2208988800L;

          buffer[(offset++)] = (byte)(int)(seconds >> 24);
          buffer[(offset++)] = (byte)(int)(seconds >> 16);
          buffer[(offset++)] = (byte)(int)(seconds >> 8);
          buffer[(offset++)] = (byte)(int)(seconds >> 0);

          long fraction = milliseconds * 4294967296L / 1000L;

          buffer[(offset++)] = (byte)(int)(fraction >> 24);
          buffer[(offset++)] = (byte)(int)(fraction >> 16);
          buffer[(offset++)] = (byte)(int)(fraction >> 8);

          buffer[(offset++)] = (byte)(int)(Math.random() * 255.0D);
        }
      }

      @BA.ActivityObject
      @BA.ShortName("SntpTime")
      public static class SntpTime
      {
        public long getGmtNtpTime(BA ba)
        {
          SPSntp.SntpClient client = new SPSntp.SntpClient(null);

          SPSntp.mNtpTime = Long.valueOf(-1L).longValue();
          SPSntp.mNtpTimeReference = Long.valueOf(-1L).longValue();
          SPSntp.mRoundTripTime = Long.valueOf(-1L).longValue();
          try {
            client.requestTime(SPSntp.mNtpServerName, SPSntp.mTimeOut);
          }
          catch (Exception localException)
          {
          }

          return SPSntp.mNtpTime;
        }

        public long getNtpTimeReference()
        {
          return SPSntp.mNtpTimeReference;
        }

        public long getRoundTripTime()
        {
          return SPSntp.mRoundTripTime;
        }

        public void setNtpServerName(String ntpServerName)
        {
          SPSntp.mNtpServerName = ntpServerName;
        }

        public void setTimeOut(int timeOut)
        {
          SPSntp.mTimeOut = timeOut;
        }
      }
    }
     
  8. Erel

    Erel Administrator Staff Member Licensed User

    Your Java code is based on UDP not TCP.
     
  9. Filippo

    Filippo Expert Licensed User

    And how can I change it to UDP? :confused:
    I find no solution.:(
     
  10. Erel

    Erel Administrator Staff Member Licensed User

    Use UDPPacket instead of Socket.
     
  11. Filippo

    Filippo Expert Licensed User

    Do you think it could work?
    Code:
    Private UDPSocket1 As UDPSocket

    Sub GetUDPatomtime
        
    Dim data() As Byte
        
    Dim UDPPacket1 As UDPPacket
        UDPSocket1.Initialize(
    "UDPSocket1"12348)
      
        UDPPacket1.Initialize(data, 
    "de.pool.ntp.org"123)

        UDPSocket1.Send(UDPPacket1)
    End Sub

    Sub UDPSocket1_PacketArrived(Packet As UDPPacket)
        
    Dim msg As String
        msg = 
    BytesToString(Packet.Data, 0, Packet.Data.Length, "UTF8")
        TextView1.Text = TextView1.Text & msg & 
    CRLF
    End Sub
     
  12. Erel

    Erel Administrator Staff Member Licensed User

    The java code you posted writes some date (27, time stamp). You will probably need to implement this protocol.
     
  13. Filippo

    Filippo Expert Licensed User

    I've done it!
    Only the packet format is not correct.
    Code:
    Sub GetUDPatomtime
        
    Dim data(48As Byte
        
    Dim UDPPacket1 As UDPPacket
        UDPSocket1.Initialize(
    "UDPSocket1"048)
       
        data(
    0) = 27
        UDPPacket1.Initialize(data, 
    "de.pool.ntp.org"123)

        UDPSocket1.Send(UDPPacket1)
    End Sub

    Sub UDPSocket1_PacketArrived(Packet As UDPPacket)
        
    Dim msg As String
        msg = 
    BytesToString(Packet.Data, 0, Packet.Data.Length, "UTF-8")
        EditText1.Text = EditText1.Text & msg & 
    CRLF
        
    Log(msg)
    End Sub
    Log:
     
    inakigarm likes this.
  14. Filippo

    Filippo Expert Licensed User

    Hi Erel,

    I need really your help.
    I have the same code once in B4a and once in B4i. Both code bring different results and both wrong.
    Where could be the problem?

    B4i-Code:
    Code:
    Sub GetUDPatomtime
        
    Dim data(48As Byte
        
    Dim UDPPacket1 As UDPPacket
        UDPSocket1.Initialize(
    "UDPSocket1"048)
       
        data(
    0) = 27
        UDPPacket1.Initialize(data, 
    "de.pool.ntp.org"123)

        UDPSocket1.Send(UDPPacket1)
    End Sub

    Sub UDPSocket1_PacketArrived(Packet As UDPPacket)
        
    Dim offsetTransmitTime As Byte = 40
        
    Dim intpart As Long = 0
        
    Dim fractpart As Long = 0
        
    For i = 0 To 3
            intpart = 
    256 * intpart + Packet.data(offsetTransmitTime + i)
        
    Next

        
    For i = 4 To 7
            fractpart = 
    256 * fractpart + Packet.data(offsetTransmitTime + i)
        
    Next

        
    Dim milliseconds As Long = (intpart * 1000 + (fractpart * 1000) / 4294967296)

        
    Dim timeSpan__1 As Long = milliseconds '* 1000
        Dim DateTime1 As Long = DateTime.DateParse("1900-01-01")
        DateTime1 = DateTime1 + timeSpan__1
        
    Log("DateTime1= " & DateTime1)

        lngTimer = 
    DateTime.Now - (DateTime.TimeZoneOffset * DateTime.TicksPerHour) - DateTime1

        
    Log("lngTimer= " & lngTimer)

        UDPSocket1.Close
    End Sub
    B4i-Log:
    B4a-Code:

    Code:
    Sub GetUDPatomtime
        
    Dim data(48As Byte
        
    Dim UDPPacket1 As UDPPacket
        UDPSocket1.Initialize(
    "UDPSocket1"048)
       
        data(
    0) = 27
        UDPPacket1.Initialize(data, 
    "de.pool.ntp.org"123)

        UDPSocket1.Send(UDPPacket1)
    End Sub

    Sub UDPSocket1_PacketArrived(Packet As UDPPacket)
        
    Dim offsetTransmitTime As Byte = 40
        
    Dim intpart As Long = 0
        
    Dim fractpart As Long = 0
        
    For i = 0 To 3
            intpart = 
    256 * intpart + Packet.Data(offsetTransmitTime + i)
        
    Next

        
    For i = 4 To 7
            fractpart = 
    256 * fractpart + Packet.Data(offsetTransmitTime + i)
        
    Next

        
    Dim milliseconds As Long = (intpart * 1000 + (fractpart * 1000) / 4294967296)

        
    Dim timeSpan__1 As Long = milliseconds '* 1000
        Dim DateTime1 As Long = DateTime.DateParse("1900-01-01")
        DateTime1 = DateTime1 + timeSpan__1
        
    Log("DateTime1= " & DateTime1)

        lngTimer = 
    DateTime.Now - (DateTime.TimeZoneOffset * DateTime.TicksPerHour) - DateTime1
       
        
    Log("lngTimer= " & lngTimer)

        UDPSocket1.Close
    End Sub
    B4a-Log:
     
  15. Filippo

    Filippo Expert Licensed User

    I have it solved. :)

    Code:
    Sub GetUDPatomtime
        
    Dim data(48As Byte
        
    Dim UDPPacket1 As UDPPacket
        UDPSocket1.Initialize(
    "UDPSocket1"048)
       
        data(
    0) = 27
        UDPPacket1.Initialize(data, 
    "de.pool.ntp.org"123)

        UDPSocket1.Send(UDPPacket1)
    End Sub

    Sub UDPSocket1_PacketArrived(Packet As UDPPacket)
        
    '++++++ Test ++++++
    '    Dim str As String = ""
    '    For i = 0 To Packet.data.Length - 1
    '        str = str & Packet.data(i) & " "
    '    Next
    '    Log(str)
        '++++++ Test ++++++

        
    Dim offsetTransmitTime As Byte = 40
        
    Dim OFFSET_1900_TO_1970 As Long = 2208988800
        
    Dim Year_1900_01_01 As Long = 4294967296
        
    Dim seconds As Long = 0
        
    Dim fraction As Long = 0
        
    For i = 0 To 3
            seconds = 
    256 * seconds + Packet.data(offsetTransmitTime + i)
        
    Next

        
    For i = 4 To 7
            fraction = 
    256 * fraction + Packet.data(offsetTransmitTime + i)
        
    Next

        
    Dim ntpTime As Long
        ntpTime = (seconds - OFFSET_1900_TO_1970) * 
    1000 + (fraction * 1000) / Year_1900_01_01

        lngTimer = 
    DateTime.Now - ntpTime

        
    Log("lngTimer= " & lngTimer)

        UDPSocket1.Close
    End Sub
     
Loading...