简单的NTP客户端-C语言实现

创建时间: 2017-09-11
最后修改时间: 2017-09-11

因个人水平有限,文章中存在不足,错误之处,还望指正

实验环境
Linux 2.6.32
gcc version 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC)

引言

本NTP客户端实现是基于NTPv3单播模式来实现的,其中参考了SNTP的实现(SNTP为NTP的简化版)。

要完成客户端的开发需要准备一些知识,比如NTP工作模式,NTP报文格式等等,大体了解完这些后才能更好地掌握整个开发过程。

NTP协议

简介

NTP(Network Time Protocol),网络时间协议,应用于分布式时间服务器和客户端之间,实现客户端和服务器之间的时间同步,从而使网络内所有设备的时间基本保持一致。NTP工作于UDP的123端口。

NTP报文格式
0   2     5     8               16              24              32
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|LI | VN  |Mode |    Stratum    |     Poll      |   Precision   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          Root Delay                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Root Dispersion                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                     Reference Identifier                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                   Reference Timestamp (64)                    |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                   Originate Timestamp (64)                    |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                   Receive Timestamp (64)                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                   Transmit Timestamp (64)                     |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                  Authentication (optional) (64)               |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                            NTPv3报文格式
  • Leap Indicator(LI)
    闰秒指示符,这是一个2位的代码,用于警示在当天的最后一分钟里插入或删除的闰秒。取值如下:

    0       无预告
    1       最近一分钟有61秒
    2       最近一分钟有59秒
    3       警告状态(时钟未同步)
    
  • Version Number(VN)
    版本号,这是一个3位的整数,用于表示NTP的版本。

  • Mode
    模式,这是一个3位的整数,表示模式,值定义如下:

    0           保留
    1           对称主动
    2           对称被动
    3           客户端
    4           服务器端
    5           广播
    6           为NTP控制控制消息
    7           为自用保留
    
  • Stratum
    本地时钟层级,这是一个八位无符号整数,表示本地时钟的层级,其值定义如下:

    0           未定义或难以获得
    1           主要参考(如无线电时钟钟,校正的院子时钟)
    2-255       第二参考(通过NTP或SNTP)
    
  • Poll
    轮询间隔,这是一个8位有符号整数,用于表示连续消息之间的最大间隔,以最接近2的N次幂来表示。如值为6表示2^6=64。

  • Precision
    本地时钟精度精度,这是一个8位有符号整数,用于表示本地时钟精度,以最接近2的N次幂来表示。

  • Root Delay
    这是一个32位有符号定点数,表示主要参考源的总往返时延,以秒为单位。该变量可以为正值和负值,具体取决于时间精度和偏移。

  • Root Dispersion
    这是一个32位有符号定点数,表示相对于主参考源的最大误差,以秒为单位,在15和16位之间。通常在该字段中出现的值范围为0到几百毫秒

  • Reference Identifier
    这是一个标识特定参考源的32位位串。在NTP版本3或版本4层级0或层级1服务器的情况下,这是一个4字符ASCII字符串,左对齐并且以0填充到32位。在NTP版本3辅助服务器中,这是参考源的32位IPv4地址。

  • Reference Timestamp
    这是以64位时间戳格式表示的上次设置或更正的本地时钟时间。

  • Original Timestamp
    这是以64位时间戳格式表示的请求离开客户端的时间。

  • Receive Timestamp
    这是以64位时间戳格式表示的请求到达服务器端的时间。

  • Transmit Timestamp
    这是以64位时间戳格式表示的应答离开服务器端的时间。

  • Authentication
    认证信息。

NTP时间戳
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Integer Part                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Fraction Part                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                            NTP时间戳格式

NTP时间戳使用的是自1970-01-01所经过的秒数(单位为秒),它分为整数部分和小数部分。NTP时间戳整数部分与ICMP时间戳消息所使用的时间戳格式整数部分一致,但小数部分却是不同的。

在64位的NTP时间戳中,前32位为整数部分,后32位为小数部分,其转换如下:

frac * 1e6 / (2<<32)    
= frac /  4294.
  • 20
    点赞
  • 90
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
### 回答1: 学习51单片机和C语言编程,可以帮助我们更深入地理解嵌入式系统的原理和工作方式。对于初学者来说,掌握一份适合自己的学习资料非常重要。 要学习51单片机-C语言版,可以阅读《手把手教你学51单片机-C语言版pdf》这本电子书,这本书内容丰富,讲解详细,配合实例编程,非常适合初学者自学。以下是学习本书的几个关键点: 第一,掌握基本的硬件知识,包括单片机的结构和特性,尤其是各种寄存器的作用和配置方法。 第二,了解C语言编程基础,尤其是语法、数据类型、运算符、控制结构、函数等,这是编写单片机程序的基础。 第三,通过实例编程加强对知识的理解和运用能力。例如,可以尝试写一些简单的IO控制、定时器中断、串口通讯等程序。 第四,可以搭配相应的开发板和开发环境进行实践学习。例如,可以使用STC89C51开发板和Keil或SDCC开发环境。 总之,《手把手教你学51单片机-C语言版pdf》这本电子书是一个不错的学习资料,但也需要具备一定的基础知识和耐心,可以结合其他资料和实践不断提高自己的能力。 ### 回答2: 学习51单片机-c语言版, 需要基础的C语言编程知识。在学习前,先要熟悉C语言的数据类型、循环、判断及函数等语法结构,并掌握C语言的编写方法。 在学习51单片机-c语言版之前,需要准备好学习环境,如下载并安装Keil软件, 安装并关联好相应的单片机模拟器。Keil软件中有类似于记事本的编辑窗口用来编写C语言代码, 以及编译,调试和下载程序到单片机等功能。 在学习时,可以选择一些简单的例程开始学习,逐步理解其代码逻辑,了解基本的寄存器操作和中断等知识。可以从LED灯等简单的实验开始,逐渐增加难度和功能的复杂度。 同时,可以参考一些权威的学习资料如《单片机原理与应用》、《51单片机学习与应用》等相关书籍,或结合网络资源进行学习。在学习过程中,需要勤加练习,多编写代码进行实践,同时多与他人交流学习体会和技术问题。通过坚持不断的学习和练习,便可以逐步掌握51单片机-c语言版编程技巧,提高自己的单片机应用开发能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值