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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 百度云个人服务器搭建

    百度云个人服务器搭建百度云个人服务器搭建前言背景​ 前段时间看了一些文章,就突发奇想的想自己做一个小程序。于是乎有了需求,然后自然就去实现他了。因为没有搭建过自己的服务器,其中的过程也挺有意思的,所以就写下来,纪念纪念。大家也就图个乐呵看看,搭建的步骤仅供参考~~​ 至于为什么是百度云的服务器,咳咳,是因为刚刚好发现百度云在做活动,1000多的服务器只要300多,对于我这种穷屌丝来说,试试手,成本低一点当然很重…

    2022年5月9日
    47
  • javah是什么命令_SQL命令

    javah是什么命令_SQL命令今天看了《android框架揭秘》一书中的jni这块,按照书上的写法试了试javah命令,  今天通过javah生成h文件时遇到各种问题。不管是javah-classpath参数啊还是别的什么,一直都无法成功通过class文件生成h文件。  想了想应该是路径问题,现在终于成功编译出来了~  先在cmd命令行里面切换到工程的目录  调用javah命令时,j

    2022年9月24日
    0
  • 什么是友元类[通俗易懂]

    什么是友元类[通俗易懂]======================什么是友元类=======================     当一个类B成为了另外一个类A的“朋友”时,那么类A的私有和保护的数据成员就可以被类B访问。我们就把类B叫做类A的友元。=======================友元类能做什么=======================     友元类可以通过自己的方法来

    2025年5月26日
    1
  • C# winform DataGridView 常见属性

    C# winform DataGridView 常见属性C#winformDataGridView属性说明① 取得或者修改当前单元格的内容② 设定单元格只读③ 不显示最下面的新行④ 判断新增行⑤ 行的用户删除操作的自定义⑥ 行、列的隐藏和删

    2022年7月1日
    23
  • docker 镜像导入导出_镜像导出

    docker 镜像导入导出_镜像导出Docker镜像的导入导出本文介绍Docker镜像的导入导出,用于迁移、备份、升级等场景,准备环境如下:CentOS7.0Docker1.18导入导出命令介绍涉及的命令有export、import、save、loadsave命令dockersave[options]images[images…]示例dockersave-…

    2022年9月16日
    0
  • internal server error wamp「建议收藏」

    internal server error wamp「建议收藏」找到wamp下的httpd.conf文件开启:mod_rewrite.so然后重启就apache服务就可以了!注:打开httpd.conf文件后搜索“mod_rewrite.so”把前面的#去掉也就是开启此功能了!

    2022年7月12日
    14

发表回复

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

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