Internet Date

User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Internet Date

Post by Antonio Linares »

Lets make a try from scratch (based on sntp.cpp code):

GetSNTP( cServer, ::nPort, ::lSync )

Code: Select all

struct NtpServerResponse
{
  int m_nLeapIndicator; //0: no warning
                        //1: last minute in day has 61 seconds
                        //2: last minute has 59 seconds
                        //3: clock not synchronized

  int m_nStratum; //0: unspecified or unavailable
                  //1: primary reference (e.g., radio clock)
                  //2-15: secondary reference (via NTP or SNTP)
                  //16-255: reserved

  CNtpTime     m_OriginateTime;    //Time when the request was sent from the client to the SNTP server
  CNtpTime     m_ReceiveTime;      //Time when the request was received by the server
  CNtpTime     m_TransmitTime;     //Time when the server sent the request back to the client
  CNtpTime     m_DestinationTime;  //Time when the reply was received by the client
  double       m_RoundTripDelay;   //Round trip time in seconds
  double       m_LocalClockOffset; //Local clock offset relative to the server
};

HB_FUNC( GETSNTP )
{
   SOCKET m_hSocket = socket( AF_INET, SOCK_DGRAM, 0 );
   SOCKADDR_IN sockAddr;
   NtpBasicInfo nbi;
   int nSendSize = sizeof( NtpBasicInfo );
   NtpFullPacket nfp;
   int nReceiveSize = sizeof( NtpFullPacket );
   NtpServerResponse response;

   ZeroMemory( &sockAddr, sizeof( sockAddr ) );
   sockAddr.sin_family = AF_INET;
   sockAddr.sin_port = htons( ( u_short ) hb_parnl( 2 ) ); // nPort 
   sockAddr.sin_addr.s_addr = inet_addr( hb_parc( 1 ) ); // lpszAscii   

   if (sockAddr.sin_addr.s_addr == INADDR_NONE)
   {
      LPHOSTENT lphost = gethostbyname( hb_parc( 1 ) );
        
      if (lphost != NULL)
         sockAddr.sin_addr.s_addr = ( ( LPIN_ADDR ) lphost->h_addr )->s_addr;
   }

   connect( m_hSocket, &sockAddr, sizeof( sockAddr ) );

   ZeroMemory( &nbi, nSendSize );
   nbi.m_LiVnMode = 27; //Encoded representation which represents NTP Client Request & NTP version 3.0
   nbi.m_TransmitTimestamp = CNtpTime_GetCurrentTime();

   send( m_hSocket, (LPCSTR) &nbi, nSendSize, 0 );

   ZeroMemory( &nfp, nReceiveSize );

   recv( m_hSocket, ( LPSTR ) &nfp, nReceiveSize, 0 ); 

    response.m_nStratum = nfp.m_Basic.m_Stratum;
    response.m_nLeapIndicator = (nfp.m_Basic.m_LiVnMode & 0xC0) >> 6;
    response.m_OriginateTime = nfp.m_Basic.m_OriginateTimestamp;
    response.m_ReceiveTime = nfp.m_Basic.m_ReceiveTimestamp;
    response.m_TransmitTime = nfp.m_Basic.m_TransmitTimestamp;
    response.m_RoundTripDelay = (response.m_DestinationTime - response.m_OriginateTime) - (response.m_ReceiveTime - response.m_TransmitTime);
    response.m_LocalClockOffset = ((response.m_ReceiveTime - response.m_OriginateTime) + (response.m_TransmitTime - response.m_DestinationTime)) / 2;

   hb_retclen( ( char * ) &response, sizeof( response ) );
}
 
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
albeiroval
Posts: 323
Joined: Tue Oct 16, 2007 5:51 pm
Location: Barquisimeto - Venezuela

Re: Internet Date

Post by albeiroval »

Antonio, buen dia,

Me dan los siguientes errores :

Code: Select all

����������������������������������������������������������������������������Ŀ
� FiveWin for Harbour 13.01 - Jan.  2013          Harbour development power  ��
� (c) FiveTech, 1993-2013   for Microsoft Windows 9X/NT/200X/ME/XP/Vista/7/8 ��
�������������������������������������������������������������������������������
� �����������������������������������������������������������������������������
Compiling...
Harbour 3.2.0dev (r1306132159)
Copyright (c) 1999-2013, http://harbour-project.org/
Compiling 'D:\TESTSA~1\timezone.prg' and generating preprocessed output to 'D:\TESTSA~1\timezone.ppo'...

100

100

200

300

400

500

100

Lines 1072, Functions/Procedures 7
Generating C source output to 'timezone.c'... Done.
Borland C++ 5.82 for Win32 Copyright (c) 1993, 2005 Borland
D:\TESTSA~1\timezone.c:
Error E2139 D:\\TESTSA~1\\timezone.prg 139: Declaration missing ;
Error E2238 D:\\TESTSA~1\\timezone.prg 140: Multiple declaration for 'CNtpTime'
Error E2344 D:\\TESTSA~1\\timezone.prg 139: Earlier declaration of 'CNtpTime'
Error E2139 D:\\TESTSA~1\\timezone.prg 140: Declaration missing ;
Error E2238 D:\\TESTSA~1\\timezone.prg 141: Multiple declaration for 'CNtpTime'
Error E2344 D:\\TESTSA~1\\timezone.prg 139: Earlier declaration of 'CNtpTime'
Error E2139 D:\\TESTSA~1\\timezone.prg 141: Declaration missing ;
Error E2238 D:\\TESTSA~1\\timezone.prg 142: Multiple declaration for 'CNtpTime'
Error E2344 D:\\TESTSA~1\\timezone.prg 139: Earlier declaration of 'CNtpTime'
Error E2139 D:\\TESTSA~1\\timezone.prg 142: Declaration missing ;
Error E2451 D:\\TESTSA~1\\timezone.prg 151: Undefined symbol 'NtpBasicInfo' in function HB_FUN_GETSNTP
Error E2379 D:\\TESTSA~1\\timezone.prg 151: Statement missing ; in function HB_FUN_GETSNTP
Error E2140 D:\\TESTSA~1\\timezone.prg 152: Declaration is not allowed here in function HB_FUN_GETSNTP
Error E2109 D:\\TESTSA~1\\timezone.prg 152: Not an allowed type in function HB_FUN_GETSNTP
Error E2451 D:\\TESTSA~1\\timezone.prg 153: Undefined symbol 'NtpFullPacket' in function HB_FUN_GETSNTP
Error E2379 D:\\TESTSA~1\\timezone.prg 153: Statement missing ; in function HB_FUN_GETSNTP
Error E2140 D:\\TESTSA~1\\timezone.prg 154: Declaration is not allowed here in function HB_FUN_GETSNTP
Error E2109 D:\\TESTSA~1\\timezone.prg 154: Not an allowed type in function HB_FUN_GETSNTP
Error E2451 D:\\TESTSA~1\\timezone.prg 155: Undefined symbol 'NtpServerResponse' in function HB_FUN_GETSNTP
Error E2379 D:\\TESTSA~1\\timezone.prg 155: Statement missing ; in function HB_FUN_GETSNTP
Warning W8065 D:\\TESTSA~1\\timezone.prg 159: Call to function 'hb_parnl' with no prototype in function HB_FUN_GETSNTP
Warning W8065 D:\\TESTSA~1\\timezone.prg 160: Call to function 'hb_parc' with no prototype in function HB_FUN_GETSNTP
Error E2342 D:\\TESTSA~1\\timezone.prg 160: Type mismatch in parameter 'cp' (wanted 'const signed char *', got 'int') in function HB_FUN_GETSNTP
Warning W8065 D:\\TESTSA~1\\timezone.prg 164: Call to function 'hb_parc' with no prototype in function HB_FUN_GETSNTP
Error E2342 D:\\TESTSA~1\\timezone.prg 164: Type mismatch in parameter 'name' (wanted 'const signed char *', got 'int') in function HB_FUN_GETSNTP
Warning W8075 D:\\TESTSA~1\\timezone.prg 170: Suspicious pointer conversion in function HB_FUN_GETSNTP
Error E2451 D:\\TESTSA~1\\timezone.prg 172: Undefined symbol 'nbi' in function HB_FUN_GETSNTP
Warning W8065 D:\\TESTSA~1\\timezone.prg 174: Call to function 'CNtpTime_GetCurrentTime' with no prototype in function HB_FUN_GETSNTP
Error E2451 D:\\TESTSA~1\\timezone.prg 178: Undefined symbol 'nfp' in function HB_FUN_GETSNTP
Error E2451 D:\\TESTSA~1\\timezone.prg 182: Undefined symbol 'response' in function HB_FUN_GETSNTP
Error E2228 D:\\TESTSA~1\\timezone.prg 182: Too many error or warning messages in function HB_FUN_GETSNTP
*** 26 errors in Compile ***
* Linking errors *

 

Aqui el Prg :

Code: Select all

#include "hbclass.ch"
#include "common.ch"

//----------------------------------------// 

Function Main()
  ? Test()
Return Nil

//----------------------------------------// 

static Function Test()
  Local aNet      := {},;
        nPort     := 123,;
        cIp       := "time.windows.com",;
        lSync     := .T.,;
        oSntp     := NIL,;
            cNetDate  := ""
  
  oSntp := TSntp():New( cIP, nPort, lSync )

  If oSntp:GetData()
     // orignal code:   ? oSntp:Date(), "date"
     cNetDate := oSntp:Date()
  Else
     cNetDate := "99/99/99"
  EndIf

Return  cNetDate 
 
//----------------------------------------// 

CLASS TSNTP

  DATA  cServer,;       // server name/ip
            nPort,;         // server port
        lSync,;         // Sync flag
        lError

  DATA  nYear,;
        nMonth,;
        nDay,;
        nWeek,;
        nDayOfYear

  DATA  nHours,;
        nMinute,;
        nSeconds

  METHOD  New(cServer, nPort, lSync)
  METHOD  GetData()
  MESSAGE DATE    METHOD  _Date()
  MESSAGE TIME    METHOD  _Time()

ENDCLASS

//----------------------------------------// 

METHOD  New( cServer, nPort, lSync ) CLASS TSNTP
    DEFAULT cServer to "time.windows.com"   // ????
    DEFAULT nPort   to 123                  // ?? port
    DEFAULT lSync   to .F.                  // ????

  ::cServer   := cServer
  ::nPort     := nPort
  ::lSync     := lSync
  ::lError    := .F.

RETURN  Self

//----------------------------------------// 

METHOD GetData() CLASS TSNTP
  Local   xRet    := GetSNTP( ::cServer, ::nPort, ::lSync )
  
  If ValType(xRet) == "N"
     ::lError   := .T.
     ::nYear    := 0
     ::nMonth   := 0
     ::nDay     := 0
     ::nHours   := 0
     ::nMinute  := 0
     ::nSeconds := 0
     ::nWeek    := 0
     ::nDayOfYear := 0
  Else
     ::lError := .F.
     //          0        1         2
     //          12345678901234567890
     // ???? yyyymmddhhmmsswyda
     ::nYear    := Val( Substr( xRet,  1, 4 ))
     ::nMonth   := Val( Substr( xRet,  5, 2 ))
     ::nDay     := Val( Substr( xRet,  7, 2 ))
     ::nHours   := Val( Substr( xRet,  9, 2 ))
     ::nMinute  := Val( Substr( xRet, 11, 2 ))
     ::nSeconds := Val( Substr( xRet, 13, 2 ))
     ::nWeek    := Val( Substr( xRet, 15, 1 ))
     ::nDayOfYear := Val( Substr( xRet, 16, 3 ))
  EndIf

RETURN  ! ::lError

//----------------------------------------// 

METHOD  _Date() CLASS TSNTP
RETURN  StoD( PadL( ::nYear, 4, "0" )+;
              PadL( ::nMonth, 2, "0" )+;
              PadL( ::nDay, 2, "0" ) )

//----------------------------------------// 

METHOD  _Time() CLASS TSNTP
RETURN  PadL( ::nHours, 2, "0" )+":"+;
        PadL( ::nMinute, 2, "0" )+":"+;
        PadL( ::nSeconds, 2, "0" )
        
// Antonio linarez        
// GetSNTP( cServer, ::nPort, ::lSync )        

//----------------------------------------// 

#pragma BEGINDUMP

#include <windows.h>


struct NtpServerResponse
{
  int m_nLeapIndicator; //0: no warning
                        //1: last minute in day has 61 seconds
                        //2: last minute has 59 seconds
                        //3: clock not synchronized

  int m_nStratum; //0: unspecified or unavailable
                  //1: primary reference (e.g., radio clock)
                  //2-15: secondary reference (via NTP or SNTP)
                  //16-255: reserved

  CNtpTime     m_OriginateTime;    //Time when the request was sent from the client to the SNTP server
  CNtpTime     m_ReceiveTime;      //Time when the request was received by the server
  CNtpTime     m_TransmitTime;     //Time when the server sent the request back to the client
  CNtpTime     m_DestinationTime;  //Time when the reply was received by the client
  double       m_RoundTripDelay;   //Round trip time in seconds
  double       m_LocalClockOffset; //Local clock offset relative to the server
};

HB_FUNC( GETSNTP )
{
   SOCKET m_hSocket = socket( AF_INET, SOCK_DGRAM, 0 );
   SOCKADDR_IN sockAddr;
   NtpBasicInfo nbi;
   int nSendSize = sizeof( NtpBasicInfo );
   NtpFullPacket nfp;
   int nReceiveSize = sizeof( NtpFullPacket );
   NtpServerResponse response;

   ZeroMemory( &sockAddr, sizeof( sockAddr ) );
   sockAddr.sin_family = AF_INET;
   sockAddr.sin_port = htons( ( u_short ) hb_parnl( 2 ) ); // nPort 
   sockAddr.sin_addr.s_addr = inet_addr( hb_parc( 1 ) ); // lpszAscii   

   if (sockAddr.sin_addr.s_addr == INADDR_NONE)
   {
      LPHOSTENT lphost = gethostbyname( hb_parc( 1 ) );
        
      if (lphost != NULL)
         sockAddr.sin_addr.s_addr = ( ( LPIN_ADDR ) lphost->h_addr )->s_addr;
   }

   connect( m_hSocket, &sockAddr, sizeof( sockAddr ) );

   ZeroMemory( &nbi, nSendSize );
   nbi.m_LiVnMode = 27; //Encoded representation which represents NTP Client Request & NTP version 3.0
   nbi.m_TransmitTimestamp = CNtpTime_GetCurrentTime();

   send( m_hSocket, (LPCSTR) &nbi, nSendSize, 0 );

   ZeroMemory( &nfp, nReceiveSize );

   recv( m_hSocket, ( LPSTR ) &nfp, nReceiveSize, 0 ); 

    response.m_nStratum = nfp.m_Basic.m_Stratum;
    response.m_nLeapIndicator = (nfp.m_Basic.m_LiVnMode & 0xC0) >> 6;
    response.m_OriginateTime = nfp.m_Basic.m_OriginateTimestamp;
    response.m_ReceiveTime = nfp.m_Basic.m_ReceiveTimestamp;
    response.m_TransmitTime = nfp.m_Basic.m_TransmitTimestamp;
    response.m_RoundTripDelay = (response.m_DestinationTime - response.m_OriginateTime) - (response.m_ReceiveTime - response.m_TransmitTime);
    response.m_LocalClockOffset = ((response.m_ReceiveTime - response.m_OriginateTime) + (response.m_TransmitTime - response.m_DestinationTime)) / 2;
}
 
#pragma ENDDUMP 
 
Saludos,
Regards,

Albeiro Valencia
www.avcsistemas.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Internet Date

Post by Antonio Linares »

regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Internet Date

Post by Antonio Linares »

Building it from last url source code:

Code: Select all

// Internet time

#include "FiveWin.ch"

function Main()

   MsgInfo( GetNtpDate( "65.55.56.206" ) ) // time.microsoft.com

return nil

#pragma BEGINDUMP

#include <hbapi.h>
#include <winsock.h>

#define MAXLEN 1024

HB_FUNC( GETNTPDATE )
{
   char * hostname = ( char * ) hb_parc( 1 );
   int  portno = 123;   // NTP is port 123
   int  i;          // misc var i
   unsigned char msg[ 48 ] = { 010, 0, 0, 0, 0, 0, 0, 0, 0 };   // the packet we send
   unsigned long  buf[ MAXLEN ];    // the buffer we get back
   struct protoent * proto;     //
   struct sockaddr_in server_addr;
   int  s;  // socket
   int  tmit;   // the time -- This is a time_t sort of
   WSADATA wsa;
     
   WSAStartup( 0x101, &wsa );    
   proto = getprotobyname( "udp" );
   s = socket( PF_INET, SOCK_DGRAM, proto->p_proto );

   memset( &server_addr, 0, sizeof( server_addr ) );
   server_addr.sin_family = AF_INET;
   server_addr.sin_addr.s_addr = inet_addr( hostname );
   server_addr.sin_port = htons( portno );
   
   i = sendto( s, msg, sizeof( msg ), 0, ( struct sockaddr * ) &server_addr, sizeof( server_addr ) );
   hb_retnl( WSAGetLastError() );   
}

#pragma ENDDUMP
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Internet Date

Post by Antonio Linares »

Enhanced version, still on development:

Code: Select all

// Internet time

#include "FiveWin.ch"

function Main()

   MsgInfo( GetNtpDate( "65.55.56.206" ) ) // time.microsoft.com

return nil

#pragma BEGINDUMP

#include <hbapi.h>
#include <winsock.h>

#define MAXLEN 1024

HB_FUNC( GETNTPDATE )
{
   char * hostname = ( char * ) hb_parc( 1 );
   int  portno = 123;   // NTP is port 123
   int  i;          // misc var i
   unsigned char msg[ 48 ] = { 010, 0, 0, 0, 0, 0, 0, 0, 0 };   // the packet we send
   unsigned long  buf[ MAXLEN ];    // the buffer we get back
   struct protoent * proto;     //
   struct sockaddr_in server_addr;
   int  s;  // socket
   int  tmit;   // the time -- This is a time_t sort of
   WSADATA wsa;
   struct timeval timeout;
   fd_set fds;
  
   timeout.tv_sec = 5;
   timeout.tv_usec = 0;
   FD_ZERO( &fds );
     
   WSAStartup( 0x101, &wsa );    
   proto = getprotobyname( "udp" );
   s = socket( PF_INET, SOCK_DGRAM, proto->p_proto );

   memset( &server_addr, 0, sizeof( server_addr ) );
   server_addr.sin_family = AF_INET;
   server_addr.sin_addr.s_addr = inet_addr( hostname );
   server_addr.sin_port = htons( portno );
   
   if( sendto( s, msg, sizeof( msg ), 0, ( struct sockaddr * ) &server_addr, sizeof( server_addr ) ) < 0 )
      MessageBox( 0, "can't send", "ok", 0 );   

   FD_SET( s, &fds );
   
   if( select( 0, &fds, NULL, NULL, &timeout ) )   
      i = recv( s, buf, sizeof( buf ), 0 );
   else
      MessageBox( 0, "can't read", "ok", 0 );   
   
   hb_retnl( WSAGetLastError() );   
}

#pragma ENDDUMP
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Internet Date

Post by Antonio Linares »

Its working ! :-)

Code: Select all

// Internet time

#include "FiveWin.ch"

function Main()

   MsgInfo( GetNtpDate( "204.123.2.72" ) )

return nil

#pragma BEGINDUMP

#include <hbapi.h>
#include <winsock.h>
#include <time.h>

#define MAXLEN 1024

HB_FUNC( GETNTPDATE )
{
   char * hostname = ( char * ) hb_parc( 1 );
   unsigned char msg[ 48 ] = { 010, 0, 0, 0, 0, 0, 0, 0, 0 };   // the packet we send
   unsigned long buf[ MAXLEN ]; // the buffer we get back
   struct sockaddr_in server_addr;
   int  s;  // socket
   WSADATA wsa;
   struct timeval timeout;
   fd_set fds;
   time_t tmit;
         
   WSAStartup( 0x101, &wsa );    

   s = socket( PF_INET, SOCK_DGRAM, getprotobyname( "udp" )->p_proto );

   memset( &server_addr, 0, sizeof( server_addr ) );
   server_addr.sin_family = AF_INET;
   server_addr.sin_addr.s_addr = inet_addr( hostname );
   server_addr.sin_port = htons( 123 ); // ntp port
   
   sendto( s, msg, sizeof( msg ), 0, ( struct sockaddr * ) &server_addr, sizeof( server_addr ) );
   
   FD_ZERO( &fds );
   FD_SET( s, &fds );
   timeout.tv_sec = 10;
   timeout.tv_usec = 0;
      
   if( select( 0, &fds, NULL, NULL, &timeout ) )
   {      
      recv( s, ( void * ) buf, sizeof( buf ), 0 );

      tmit = ntohl( buf[ 10 ] );
      tmit-= 2208988800U;
   }   
   else
      MessageBox( 0, "can't read from NTP server", "ok", 0 );      
   
   WSACleanup();

   hb_retc( ctime( &tmit ) );   
}

#pragma ENDDUMP
Image
regards, saludos

Antonio Linares
www.fivetechsoft.com
Post Reply