iOS Question Timeserver (solved)

  • Thread starter Thread starter Deleted member 103
  • Start date Start date
  • Similar Threads Similar Threads Similar Threads
D

Deleted member 103

Guest
Hi,

I can query the time from a time server and other not, someone know why?
Code: Copy
Sub GetAtomtime
    Socket1.Initialize("Socket1")
   
    'All Server work
    Socket1.Connect("time-a.nist.gov", 13, 10000)
'    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
 

Attachments

What happens when you try to connect to the ones that do not work?
Nothing happens.
This event will not fire.
Code: Copy
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
 
Upvote 0
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.
But why bring "Successful = false"?
With the Library "SPSntp" it works without problems, what's different?
 
Upvote 0
Are you sure that it listens on this port to TCP connections?
I tried also with port 123 (see java-class), unfortunately without success.
Code: Copy
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, address, 123);

        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;
    }
  }
}
 
Upvote 0
Use UDPPacket instead of Socket.
Do you think it could work?
Code: Copy
  Private UDPSocket1 As UDPSocket

Sub GetUDPatomtime
    Dim data() As Byte
    Dim UDPPacket1 As UDPPacket
    UDPSocket1.Initialize("UDPSocket1", 123, 48)
  
    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
 
Upvote 0
The java code you posted writes some date (27, time stamp). You will probably need to implement this protocol.
I've done it!
Only the packet format is not correct.
Code: Copy
Sub GetUDPatomtime
    Dim data(48) As Byte
    Dim UDPPacket1 As UDPPacket
    UDPSocket1.Initialize("UDPSocket1", 0, 48)
   
    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:
???????????5gh?"?Xp9???????????????????"??_????"??_?%@
 
Upvote 0
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: Copy
Sub GetUDPatomtime
    Dim data(48) As Byte
    Dim UDPPacket1 As UDPPacket
    UDPSocket1.Initialize("UDPSocket1", 0, 48)
   
    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:
Application_Start
DateTime1= 1434166760857
lngTimer= -3599926
Application_Active

B4a-Code:

Code: Copy
Sub GetUDPatomtime
    Dim data(48) As Byte
    Dim UDPPacket1 As UDPPacket
    UDPSocket1.Initialize("UDPSocket1", 0, 48)
   
    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:
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
DateTime1= -2860800543252
lngTimer= 4294963694622
 
Upvote 0
I have it solved. :)

Code: Copy
Sub GetUDPatomtime
    Dim data(48) As Byte
    Dim UDPPacket1 As UDPPacket
    UDPSocket1.Initialize("UDPSocket1", 0, 48)
   
    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
 
Upvote 0
Back
Top