golang ntp协议客户端
NTP(Network Time Protocol,网络时间协议)是由RFC 1305定义的时间同步协议,用来在分布式时间服务器和客户端之间进行时间同步。NTP基于UDP报文进行传输,使用的UDP端口号为123。
使用NTP的目的是对网络内所有具有时钟的设备进行时钟同步,使网络内所有设备的时钟保持一致,从而使设备能够提供基于统一时间的多种应用。
对于运行NTP的本地系统,既可以接收来自其他时钟源的同步,又可以作为时钟源同步其他的时钟,并且可以和其他设备互相同步。

相信文本介绍看多也厌倦了,就不多废话,直接上干活
ntp.go
package main import (
"bytes"
"encoding/binary"
) const (
UNIX_STA_TIMESTAMP = 2208988800
) /**
NTP协议 http://www.ntp.org/documentation.html
@author mengdj@outlook.com
*/
type Ntp struct {
//1:32bits
Li uint8 //2 bits
Vn uint8 //3 bits
Mode uint8 //3 bits
Stratum uint8
Poll uint8
Precision uint8
//2:
RootDelay int32
RootDispersion int32
ReferenceIdentifier int32
//64位时间戳
ReferenceTimestamp uint64 //指示系统时钟最后一次校准的时间
OriginateTimestamp uint64 //指示客户向服务器发起请求的时间
ReceiveTimestamp uint64 //指服务器收到客户请求的时间
TransmitTimestamp uint64 //指示服务器向客户发时间戳的时间
} func NewNtp() (p *Ntp) {
//其他参数通常都是服务器返回的
p = &Ntp{Li: 0, Vn: 3, Mode: 3, Stratum: 0}
return p
} /**
构建NTP协议信息
*/
func (this *Ntp) GetBytes() []byte {
//注意网络上使用的是大端字节排序
buf := &bytes.Buffer{}
head := (this.Li << 6) | (this.Vn << 3) | ((this.Mode << 5) >> 5)
binary.Write(buf, binary.BigEndian, uint8(head))
binary.Write(buf, binary.BigEndian, this.Stratum)
binary.Write(buf, binary.BigEndian, this.Poll)
binary.Write(buf, binary.BigEndian, this.Precision)
//写入其他字节数据
binary.Write(buf, binary.BigEndian, this.RootDelay)
binary.Write(buf, binary.BigEndian, this.RootDispersion)
binary.Write(buf, binary.BigEndian, this.ReferenceIdentifier)
binary.Write(buf, binary.BigEndian, this.ReferenceTimestamp)
binary.Write(buf, binary.BigEndian, this.OriginateTimestamp)
binary.Write(buf, binary.BigEndian, this.ReceiveTimestamp)
binary.Write(buf, binary.BigEndian, this.TransmitTimestamp)
//[27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
return buf.Bytes()
} func (this *Ntp) Parse(bf []byte, useUnixSec bool) {
var (
bit8 uint8
bit32 int32
bit64 uint64
rb *bytes.Reader
)
//貌似这binary.Read只能顺序读,不能跳着读,想要跳着读只能使用切片bf
rb = bytes.NewReader(bf)
binary.Read(rb, binary.BigEndian, &bit8)
//向右偏移6位得到前两位LI即可
this.Li = bit8 >> 6
//向右偏移2位,向右偏移5位,得到前中间3位
this.Vn = (bit8 << 2) >> 5
//向左偏移5位,然后右偏移5位得到最后3位
this.Mode = (bit8 << 5) >> 5
binary.Read(rb, binary.BigEndian, &bit8)
this.Stratum = bit8
binary.Read(rb, binary.BigEndian, &bit8)
this.Poll = bit8
binary.Read(rb, binary.BigEndian, &bit8)
this.Precision = bit8 //32bits
binary.Read(rb, binary.BigEndian, &bit32)
this.RootDelay = bit32
binary.Read(rb, binary.BigEndian, &bit32)
this.RootDispersion = bit32
binary.Read(rb, binary.BigEndian, &bit32)
this.ReferenceIdentifier = bit32 //以下几个字段都是64位时间戳(NTP都是64位的时间戳)
binary.Read(rb, binary.BigEndian, &bit64)
this.ReferenceTimestamp = bit64
binary.Read(rb, binary.BigEndian, &bit64)
this.OriginateTimestamp = bit64
binary.Read(rb, binary.BigEndian, &bit64)
this.ReceiveTimestamp = bit64
binary.Read(rb, binary.BigEndian, &bit64)
this.TransmitTimestamp = bit64
//转换为unix时间戳,先左偏移32位拿到64位时间戳的整数部分,然后ntp的起始时间戳 1900年1月1日 0时0分0秒 2208988800
if useUnixSec {
this.ReferenceTimestamp = (this.ReceiveTimestamp >> 32) - UNIX_STA_TIMESTAMP
if this.OriginateTimestamp > 0 {
this.OriginateTimestamp = (this.OriginateTimestamp >> 32) - UNIX_STA_TIMESTAMP
}
this.ReceiveTimestamp = (this.ReceiveTimestamp >> 32) - UNIX_STA_TIMESTAMP
this.TransmitTimestamp = (this.TransmitTimestamp >> 32) - UNIX_STA_TIMESTAMP
}
}
main.go
package main import (
"fmt"
"log"
"net"
) func main() {
var (
ntp *Ntp
buffer []byte
err error
ret int
)
//链接阿里云NTP服务器,NTP有很多免费服务器可以使用time.windows.com
conn, err := net.Dial("udp", "ntp1.aliyun.com:123")
defer func() {
if err := recover(); err != nil {
log.Println(err)
}
conn.Close()
}()
ntp = NewNtp()
conn.Write(ntp.GetBytes())
buffer = make([]byte, 2048)
ret, err = conn.Read(buffer)
if err == nil {
if ret > 0 {
ntp.Parse(buffer, true)
fmt.Println(fmt.Sprintf(
"LI:%d\r\n版本:%d\r\n模式:%d\r\n精度:%d\r\n轮询:%d\r\n系统精度:%d\r\n延时:%ds\r\n最大误差:%d\r\n时钟表示:%d\r\n时间戳:%d %d %d %d\r\n",
ntp.Li,
ntp.Vn,
ntp.Mode,
ntp.Stratum,
ntp.Poll,
ntp.Precision,
ntp.RootDelay,
ntp.RootDispersion,
ntp.ReferenceIdentifier,
ntp.ReferenceTimestamp,
ntp.OriginateTimestamp,
ntp.ReceiveTimestamp,
ntp.TransmitTimestamp,
))
}
}
}
源码见:https://github.com/mengdj/ntp-go
golang ntp协议客户端的更多相关文章
- 通过NTP协议进行时间同步
最近发现手机的时间不是很准了,便到网上下了一个同步时间的小程序,简单了看了一下它的原理,是通过NTP协议来实现校时的,就顺便学习了一下NTP协议,用C#写了个简单的实现. NTP(Network Ti ...
- 实现基于NTP协议的网络校时功能
无论PC端还是移动端系统都自带时间同步功能,基于的都是NTP协议,这里使用C#来实现基于NTP协议的网络校时功能(也就是实现时间同步). 1.NTP原理 NTP[Network Time Protoc ...
- NTP 协议介绍
NTP协议 NTP(Network Time Protocol,网络时间协议)是由RFC 1305定义的时间同步协议,用来在分布式时间服务器和客户端之间进行时间同步.NTP基于UDP报文进行传输,使用 ...
- 保姆级别的RabbitMQ教程!包括Java和Golang两种客户端
目录 什么是AMQP 和 JMS? 常见的MQ产品 安装RabbitMQ 启动RabbitMQ 什么是Authentication(认证) 指定RabbitMQ的启动配置文件 如何让guest用户远程 ...
- 保姆级别的RabbitMQ教程!一看就懂!(有安装教程,送安装需要的依赖包,送Java、Golang两种客户端教学Case)
保姆级别的RabbitMQ教程!一看就懂!(有安装教程,送安装需要的依赖包,送Java.Golang两种客户端教学Case) 目录 什么是AMQP 和 JMS? 常见的MQ产品 安装RabbitM ...
- 开源的C#实现WebSocket协议客户端和服务器websocket-sharp组件解析
很久没有写博客了(至少自己感觉很长时间没有写了),没办法啊,楼主也是需要生活的人啊,这段一直都在找工作什么的.(整天催我代码的人,还望多多谅解啊,我会坚持写我们的项目的,还是需要相信我的,毕竟这是一个 ...
- 使用ntp协议同步本地时间(C语言)
使用ntp协议同步本地时间 同步服务器使用的东北大学网络授时服务:ntp.neu.edu.cn更多ntp服务器 http://www.ntp.org.cn/ 源代码来自网络,经本人精简ntp部分,供大 ...
- C#实现WebSocket协议客户端和服务器websocket sharp组件实例解析
看到这篇文章的题目,估计很多人都会问,这个组件是不是有些显的无聊了,说到web通信,很多人都会想到ASP.NET SignalR,或者Nodejs等等,实现web的网络实时通讯.有关于web实时通信的 ...
- yum仓库客户端搭建和NTP时间同步客户端配置
一.yum仓库客户端搭建 yum源仓库搭建分为服务器端和客户端. 服务端主要提供软件(rpm包)和yumlist.也就是提供yum源的位置.一般是通过http或者ftp提供位置. 客户端的配置:yum ...
随机推荐
- SkyReach 团队团队展示
班级:软件工程1916|W 作业:团队作业第一次-团队展示 团队名称:SkyReach 目标:展示团队风采,磨合团队 队员姓名与学号 队员学号 队员姓名 个人博客地址 备注 221600107 陈某某 ...
- MailKit系列之附件分离
本文主要谈谈实现思路,不提供完整代码 一.分离基础 1.MIME邮件的multipart类型 引用文章:https://blog.csdn.net/wangyu13476969128/article/ ...
- WPF常见主界面的布局
一.概述 效果图: 暂时没做完,请等待 二.实现 (一)实现无边框窗口 原文:WPF 窗口去除顶部边框(正宗无边框) ============================ 最近在做一个大屏展示视频 ...
- m3u8下载转码一次完成
最近看到有部分网站开始加入视频解析服务,虽然这种服务会损害土豆优酷等视频托管商的权益,但是,烦人的广告也让我们开始寻找有没有什么比较靠谱的解决方法~实际上很多网站都在使用m3u8文件格式,里面都是视频 ...
- vertx模块HAManager高可用
HAManager public HAManager(VertxInternal vertx, DeploymentManager deploymentManager, ClusterManager ...
- 马拉车算法——poj3974
https://segmentfault.com/a/1190000008484167?tdsourcetag=s_pctim_aiomsg 讲的超好! manacher算法理解 回文串分为偶回文串和 ...
- 洛谷 P1414 又是毕业季II
题目链接 https://www.luogu.org/problemnew/show/P1414 题目背景 “叮铃铃铃”,随着高考最后一科结考铃声的敲响,三年青春时光顿时凝固于此刻.毕业的欣喜怎敌那离 ...
- Angular Material 白天模式和黑夜模式
Material design调色板 https://www.materialpalette.com/ 明暗:虽然颜色不变,但是针对白天黑夜有做不同处理. 叠加:对话框,弹出菜单,事先是没有加载的.是 ...
- Yii2 console执行定时脚本
为什么要做crontab脚本 我们的项目使用YII2开发,并不是很大的一个电商平台,pv.IP访问量并不是很高,但客户的数据是日积月累已经产生100万条数据了,之前更新订单等数据使用定时脚本直接访问内 ...
- 在Windows上使用Let加密IIS
在Windows上使用Let加密IIS https://weblog.west-wind.com/posts/2016/Feb/22/Using-Lets-Encrypt-with-IIS-on-Wi ...