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


相关推荐

  • 第七届蓝桥杯(软件类)C++决赛A组题解

    第七届蓝桥杯(软件类)C++决赛A组题解文章目录题目链接A组真题题目结构第一题随意组合第二题拼棋盘第三题打靶第四题路径之谜第五题碱基第六题圆圈舞(待补)题目链接A组真题题目结构题目类型第一题随意组合结果填空第二题拼棋盘结果填空第三题打靶代码填空第四题路径之谜程序设计第五题碱基程序设计第六题圆圈舞程序设计第一题随意组合问题重现小明被绑架到X星球的巫师W那里。其时,W正在玩弄两组数据(2358)和(1467

    2022年7月24日
    8
  • TypeScript(1)介绍与安装[通俗易懂]

    TypeScript(1)介绍与安装[通俗易懂]前言由于最近在使用vue3写项目,使用vue3的前提就是要学习TypeScript,TypeScript算是JavaScript的升级版,TypeScript包含JavaScript和自己的一些特性

    2022年7月31日
    8
  • 为什么L1正则化导致稀疏解「建议收藏」

    一、从数据先验的角度首先你要知道L1范式和L2范式是怎么来的,然后是为什么要把L1或者L2正则项加到代价函数中去.L1,L2范式来自于对数据的先验知识.如果你认为,你现有的数据来自于高斯分布,那么就应该在代价函数中加入数据先验P(x),一般由于推导和计算方便会加入对数似然,也就是log(P(x)),然后再去优化,这样最终的结果是,由于你的模型参数考虑了数据先验,模型效果当然就更好.哦对了,如果你…

    2022年4月12日
    70
  • db4o基础一[通俗易懂]

    db4o基础一[通俗易懂]1.打开数据库IObjectContainerdb=Db4oFactory.OpenFile(YapFileName);\\’c:\db4obasic.yap’//IObjectConta

    2022年7月1日
    25
  • Java开发不得不会!郑州java外包公司有哪些

    Java开发不得不会!郑州java外包公司有哪些拼多多三面惨败,java中间件、数据库与spring框架,答不上…面试开火箭,工作拧螺丝…月初有个朋友面试拼多多,一面自信满满过了,结果三面却惨败…昨天朋友约我出来讨论问题在哪里,三面就答不上了(卡壳很严重呐)。听完整个面试经历之后,我总结了一下,这次拼多多一二三面其实综合总结起来就问了五个方面的东西,分别是自我介绍+项目、java基础、中间件、数据库和spring框架,另外还问了道算法题。接下来就跟大家一起来看看拼多多的面经,看看你是否能轻松应对面试官的炮轰?技术焦虑现在的技术圈子很火热,任何技术

    2022年5月11日
    64
  • django动态路由_路由器和转换器的区别

    django动态路由_路由器和转换器的区别自定义路径转换器有时候上面的内置的url转换器并不能满足我们的需求,因此django给我们提供了一个接口可以让我们自己定义自己的url转换器django内置的路径转换器源码解析在我们自定义路由转

    2022年7月30日
    7

发表回复

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

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