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 ...
随机推荐
- 20175204 张湲祯 2018-2019-2《Java程序设计》第九周学习总结
20175204 张湲祯 2018-2019-2<Java程序设计>第九周学习总结 教材学习内容总结 -第十一章JDBC和MySQL数据库要点: 1.下载MySQL和客户端管理工具navi ...
- CentOS7.6搭建redis4.0.1 cluster集群
1. 操作系统信息: $ uname -a Linux iZbp11d57wmumnwuihb2czZ -.el7.x86_64 # SMP Fri Feb :: UTC x86_64 x86_64 ...
- Java基础11-List;Set;Map
作业解析: remove(int index); //删除指定位置的元素 List list = new ArrayList(); list.add("s1"); list.add ...
- 一个账户接管几乎所有阿里巴巴网站(CSRF漏洞+WAF绕过)
场景 文章是关于某些客户端漏洞导致几个阿里巴巴网站的帐户被接管. 条件 TL;DR 必要条件,例如JSONP,某些浏览器处理cookie等行为. 攻击原理 大多数阿里巴巴的网站加载并执行外部JavaS ...
- java程序员技术范围
1 工具 开发工具.源代码管理.构建工具.测试工具(压力.安全等).接口测试工具.反编译工具.日志工具.第三方工具等 2 java jvm.多线程.socket.io(两种方式).集合(两大接口).异 ...
- 创建Git 仓库及 克隆、拉取、和推送操作
打开网址: https://github.com/ 登录上自己创建的 Git账号 一. 创建Git 仓库 start a project---> 输入仓库 ...
- 【mysql】 快速搞定数据库迁移
工具:navicat for mysql
- django中常用的数据查询方法
https://blog.csdn.net/chen1042246612/article/details/84071006
- Nginx+IIS+asp.net mvc 实现负载均衡示例
一.Nginx官网 http://nginx.org/ 二.下载并安装Nginx 下载地址:http://nginx.org/en/download.html 启动Nginx,启动成功的话可以在任务管 ...
- [原创]iFPGA-USB2.0 FT2232H USB & UART开发板使用说明
iFPGA-USB2.0 FT2232H USB & UART 开发板使用说明 基本特性: 沉金工艺: 速度达到30MB/S以上: FT2232H USB2.0免固件开发: FPGA-USB2 ...