ntp服务器udp协议,golang实现NTP协议获取服务器时间[通俗易懂]

ntp服务器udp协议,golang实现NTP协议获取服务器时间[通俗易懂]//fileprojectmain.gopackagemainimport(“encoding/binary””fmt””net””os””os/signal””sync””time”)const(NTP_SERVER_IP=”time.windows.com”/*NTPIP*/NTP_PORT_STR=”123″/*NTP专用端口号字符串*…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

// file project main.go

package main

import (

“encoding/binary”

“fmt”

“net”

“os”

“os/signal”

“sync”

“time”

)

const (

NTP_SERVER_IP = “time.windows.com” /*NTP IP*/

NTP_PORT_STR  = “123”              /*NTP专用端口号字 符串*/

NTP_PCK_LEN   = 48

LI            = 0

VN            = 3

MODE          = 3

STRATUM       = 0

POLL          = 4

PREC          = -6

JAN_1970      = 0x83aa7e80 /* 1900年~1970年之间的时间秒数 */

)

func NTPFRAC(x int64) int64 {

return (4294*(x) + ((1981 * (x)) >> 11))

}

func USEC(x int64) int64 {

return (((x) >> 12) – 759*((((x)>>10)+32768)>>16))

}

type ntp_time struct {

coarse uint32

fine   uint32

}

type ntp_packet struct {

leap_ver_mode        byte

startum              byte

poll                 byte

precision            byte

root_delay           int

root_dispersion      int

reference_identifier int

reference_timestamp  ntp_time

originage_timestamp  ntp_time

receive_timestamp    ntp_time

transmit_timestamp   ntp_time

}

var protocol []byte

func construct_packet() ([]byte, int) {

reqData := make([]byte, NTP_PCK_LEN)

//设置16字节的包头

head := (LI << 30) | (VN << 27) | (MODE << 24) | (STRATUM << 16) | (POLL << 8) | (PREC & 0xff)

binary.BigEndian.PutUint32(reqData[0:4], uint32(head))

//设置Root Delay、Root Dispersion和Reference Indentifier

binary.BigEndian.PutUint32(reqData[4:8], uint32(1<<16))

binary.BigEndian.PutUint32(reqData[8:12], uint32(1<<16))

binary.BigEndian.PutUint32(reqData[12:16], uint32(1<<16))

//设置Timestamp部分

timeOri := JAN_1970 + time.Now().Unix()

//设置Transmit Timestamp coarse

binary.BigEndian.PutUint32(reqData[40:44], uint32(timeOri))

//设置Transmit Timestamp fine

binary.BigEndian.PutUint32(reqData[44:48], uint32(NTPFRAC(timeOri)))

return reqData, NTP_PCK_LEN

}

func main() {

protocol = make([]byte, 32)

// Resolve address

fmt.Println(“ntp begin NTC…..”)

udpAddr, errData := net.ResolveUDPAddr(“udp”, NTP_SERVER_IP+”:”+NTP_PORT_STR)

if nil != errData {

fmt.Printf(“ntp connect err: %v\n”, errData)

return

}

fmt.Println(“ntp after ResolveTCPAddr…..: “, udpAddr)

conn, err := net.DialUDP(“udp”, nil, udpAddr)

if nil != err {

fmt.Printf(“ntp net connect error: %v\n”, err)

return

}

fmt.Println(“ntp after DialUDP…..”)

data, packet_len := construct_packet()

if packet_len == 0 {

fmt.Println(“ntp packet len is 0”)

return

}

fmt.Println(“ntp begin send: %v, data: %v”, packet_len, data)

conn.SetWriteDeadline(time.Now().Add(time.Second))

size, err := conn.Write(data)

if nil != err {

fmt.Printf(“ntp write data error: %v\n”, err)

return

} else {

fmt.Printf(“ntp write len: %v\n”, size)

}

fmt.Println(“after send”)

recvBody := make([]byte, 4096)

wait := &sync.WaitGroup{}

wait.Add(1)

go func() {

defer wait.Done()

for {

fmt.Println(“ntp begin read”)

conn.SetReadDeadline(time.Now().Add(time.Second))

size, remoteAddr, err := conn.ReadFromUDP(recvBody)

if nil != err {

fmt.Printf(“ntp read data error: %v\n”, err)

} else {

fmt.Printf(“ntp read len: %v\n”, size)

}

fmt.Println(“ntp after read, remoteAddr: %v\n”, remoteAddr.String(), recvBody[:size])

break

}

}()

wait.Wait()

var dataStru ntp_packet

dataStru.transmit_timestamp.coarse = binary.BigEndian.Uint32(recvBody[40:44]) – JAN_1970

dataStru.transmit_timestamp.fine = uint32(USEC(int64(binary.BigEndian.Uint32(recvBody[44:48]))))

fmt.Println(dataStru)

//等待退出

c := make(chan os.Signal, 1)

signal.Notify(c, os.Interrupt, os.Kill)

fmt.Println(“ntp Receive ctrl-c”)

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/183733.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • ImageView.ScaleType设置,适配列表item

    ImageView.ScaleType设置,适配列表item

    2021年9月30日
    43
  • Linux下的5款主流高可用集群软件介绍[通俗易懂]

    Linux下的5款主流高可用集群软件介绍[通俗易懂]Linux集群主要分成三大类:高可用集群(HighAvailabilityCluster)、负载均衡集群(LoadBalanceCluster)、科学计算集群(HighPerformanceComputingCluster)。其中高可用集群具有保障应用程序持续提供服务的能力,可以将因软、硬件、人为造成的故障对业务的影响降低到最小程度。在高可用集群中,最常见的就是两个节点做成的HA集群,有很多通俗的名称,比如“双机热备”、“双机互备”、“双机”。而在Linux平台下常见的高可用集群软件有

    2022年10月16日
    4
  • 什么,缺“Java项目经验”找不到工作?锋哥送你80个“项目经验”[通俗易懂]

    什么,缺“Java项目经验”找不到工作?锋哥送你80个“项目经验”[通俗易懂]很多学计算机小伙伴从校园刚出来,因为没有项目经验,找工作出出碰壁,尤其是普通大学大专和本科。今天锋哥送80个“Java项目经验”给你,无套路,谢谢;看看下面的“惨剧”就知道:没项目经验,找不到工作没有项目经验,得不到面试机会对于普通大学毕业的大专或者本科生,要想找份好实习单位或者工作,还真得搞点“项目经验”,至少能有面试机会,最终才能有工作机会;经常有应届生找我,说“锋哥啊,给点项目经验啊,实在编不出来”;今天“它来了”,一次性给你80个;(资源来自互联网)截图几个大伙看看:.

    2022年6月12日
    38
  • 显示http500内部服务器错误,http500内部服务器错误,小编教你HTTP 500 内部服务器错误怎么解决…

    显示http500内部服务器错误,http500内部服务器错误,小编教你HTTP 500 内部服务器错误怎么解决…在使用电脑的时候,出现问题是我们最不想碰到的事情了。当打开网站的时候碰到“HTTP500内部服务器错误”,这会让我们非常的心烦,有时候就是因为这些故障要折腾很久,很闹心的,下面,小编给大家带来了HTTP500内部服务器错误的解决图文。很多站长在建设网站时,经常遇到程序运行时打不开的问题,有的是因为程序出现错误,无法运行,而有的是因为服务器的原因。而系统中出现的故障是用户最不想看到的,那HTTP…

    2022年8月12日
    3
  • windows api编程入门_WindowsAPI调用DLL

    windows api编程入门_WindowsAPI调用DLLTranslateMessage是用来把虚拟键消息转换为字符消息。由于Windows对所有键盘编码都是采用虚拟键的定义,这样当按键按下时,并不得字符消息,需要键盘映射转换为字符的消息。TranslateMessage函数用于将虚拟键消息转换为字符消息。字符消息被投递到调用线程的消息队列中,当下一次调用GetMessage函数时被取出。当我们敲击键盘上的某个字符键时,系统将产生WM_KEYDOW

    2022年9月12日
    2
  • 4个基本不等式的公式高中_基本不等式公式四个叫什么名字「建议收藏」

    4个基本不等式的公式高中_基本不等式公式四个叫什么名字「建议收藏」展开全部叫做平方平均数、算术平均数、几何平均数、调和平均数1.平方平均数:又名均方根(RootMeanSquare),英文62616964757a686964616fe78988e69d8331333431376632缩写为RMS。它是2次方的广义平均数的表达式,也可称为2次幂平均数。英文名为,一般缩写成RMS。2.算术平均数:又称均值,是统计学中最基本、最常用的一种平均指标,分为简单算术平均…

    2022年4月29日
    160

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号