代码之家  ›  专栏  ›  技术社区  ›  Vincent

在Linux下查询RTC和NTP时间?

  •  -1
  • Vincent  · 技术社区  · 8 年前

    Linux内核处理时间的方式有些复杂,因为它使用不同的时间源,并定期重新同步所有内容。有一些命令行工具(如 hwclock )明确查询RTC时间。但是,我想在C或C++程序内部编程。如果Linux提供命令行工具,我假设有一种方法可以通过编程实现,但是到目前为止,我还没有找到正确的函数以及如何使用它。

    所以我的问题是:

    • 如何明确地向系统请求 RTC C或C++程序中的时间?(多么 get_rtc() 功能看起来像?)
    • 如何明确地向系统请求 NTP C或C++程序中的时间?(多么 get_ntp() 功能看起来像?)
    1 回复  |  直到 8 年前
        1
  •  0
  •   dvhh    8 年前

    使用 time(time_t*) 或 clock_gettime(clockid_t,struct timespec *) 如果你希望更精确,从 time.h header 对于RTC时间。

    有一个 article describing how to get query NTP time (这是一个 google search 离开)。

    描述NTP包的结构

    typedef struct
    {
    
      uint8_t li_vn_mode;      // Eight bits. li, vn, and mode.
                               // li.   Two bits.   Leap indicator.
                               // vn.   Three bits. Version number of the protocol.
                               // mode. Three bits. Client will pick mode 3 for client.
    
      uint8_t stratum;         // Eight bits. Stratum level of the local clock.
      uint8_t poll;            // Eight bits. Maximum interval between successive messages.
      uint8_t precision;       // Eight bits. Precision of the local clock.
    
      uint32_t rootDelay;      // 32 bits. Total round trip delay time.
      uint32_t rootDispersion; // 32 bits. Max error aloud from primary clock source.
      uint32_t refId;          // 32 bits. Reference clock identifier.
    
      uint32_t refTm_s;        // 32 bits. Reference time-stamp seconds.
      uint32_t refTm_f;        // 32 bits. Reference time-stamp fraction of a second.
    
      uint32_t origTm_s;       // 32 bits. Originate time-stamp seconds.
      uint32_t origTm_f;       // 32 bits. Originate time-stamp fraction of a second.
    
      uint32_t rxTm_s;         // 32 bits. Received time-stamp seconds.
      uint32_t rxTm_f;         // 32 bits. Received time-stamp fraction of a second.
    
      uint32_t txTm_s;         // 32 bits and the most important field the client cares about. Transmit time-stamp seconds.
      uint32_t txTm_f;         // 32 bits. Transmit time-stamp fraction of a second.
    
    } ntp_packet;              // Total: 384 bits or 48 bytes.
    

    发送查询

    // Call up the server using its IP address and port number.
    
    if ( connect( sockfd, ( struct sockaddr * ) &serv_addr, sizeof( serv_addr) ) < 0 )
      error( "ERROR connecting" );
    
    // Send it the NTP packet it wants. If n == -1, it failed.
    
    n = write( sockfd, ( char* ) &packet, sizeof( ntp_packet ) );
    
    if ( n < 0 )
      error( "ERROR writing to socket" );
    

    读取响应

    // Wait and receive the packet back from the server. If n == -1, it failed.
    
    n = read( sockfd, ( char* ) &packet, sizeof( ntp_packet ) );
    
    if ( n < 0 )
      error( "ERROR reading from socket" );
    

    分析它

    // These two fields contain the time-stamp seconds as the packet left the NTP server.
    // The number of seconds correspond to the seconds passed since 1900.
    // ntohl() converts the bit/byte order from the network's to host's "endianness".
    
    packet.txTm_s = ntohl( packet.txTm_s ); // Time-stamp seconds.
    packet.txTm_f = ntohl( packet.txTm_f ); // Time-stamp fraction of a second.
    
    // Extract the 32 bits that represent the time-stamp seconds (since NTP epoch) from when the packet left the server.
    // Subtract 70 years worth of seconds from the seconds since 1900.
    // This leaves the seconds since the UNIX epoch of 1970.
    // (1900)------------------(1970)**************************************(Time Packet Left the Server)
    
    time_t txTm = ( time_t ) ( packet.txTm_s - NTP_TIMESTAMP_DELTA );
    
    推荐文章