NTP协议的真理

luominggao123 · · 5612 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

##网上整合别人的代码,对任何时区的时间差进行了整理。 ######运行程序遇到的问题 * 在ubuntu,linux,mac修改系统时间需要在root权限运行。 * window下可直接运行 * 先调用接口NtpSet(string),获取国际时区的时间。 * 然后调用接口SetSymTime(),设置系统的时间。 ```javascript package main import ( "encoding/binary" "log" "net" "os/exec" "runtime" "strconv" "strings" "time" ) var ( IDL = time.FixedZone("国际换日线", -12*3600) MIT = time.FixedZone("中途岛标准时间", -11*3600) HST = time.FixedZone("夏威夷标准时间", -10*3600) MSIT = time.FixedZone("马克萨斯群岛标准时间)", -9.5*3600) AKST = time.FixedZone("阿拉斯加标准时间", -9*3600) PSTA = time.FixedZone("太平洋标准时间", -8*3600) MST = time.FixedZone("北美山区标准时间", -7*3600) CST = time.FixedZone("北美中部标准时间", -6*3600) EST = time.FixedZone("北美东部标准时间", -5*3600) AST = time.FixedZone("大西洋标准时间", -4*3600) NST = time.FixedZone("纽芬兰岛标准时间", -3.5*3600) SAT = time.FixedZone("南美标准时间", -3*3600) BRT = time.FixedZone("巴西时间", -2*3600) GMT = time.FixedZone("格林威治标准时间", 0) CET = time.FixedZone("欧洲中部时区", 3600) EET = time.FixedZone("欧洲东部时区", 2*3600) MSK = time.FixedZone("莫斯科时区", 3*3600) IRT = time.FixedZone("伊朗标准时间", 3.5*3600) META = time.FixedZone("中东时区A", 4*3600) AFT = time.FixedZone("阿富汗标准时间", 4.5*3600) METB = time.FixedZone("中东时区B", 5*3600) IDT = time.FixedZone("印度标准时间", 5.5*3600) NPT = time.FixedZone("尼泊尔标准时间", 5*3600*45/60) BHT = time.FixedZone("孟加拉标准时间", 6*3600) MRT = time.FixedZone("缅甸标准时间", 6.5*3600) EMST = time.FixedZone("中南半岛标准时间", 7*3600) EAT = time.FixedZone("东亚标准时间/中国标准时间)", 8*3600) KRT = time.FixedZone("朝鲜标准时间", 8.5*3600) FET = time.FixedZone("远东标准时间", 9*3600) ACST = time.FixedZone("澳大利亚中部标准时间)", 9.5*3600) AEST = time.FixedZone("澳大利亚东部标准时间", 10*3600) FAST = time.FixedZone("澳大利亚远东标准时间", 10.5*3600) VTT = time.FixedZone("瓦努阿图标准时间", 11*3600) NFT = time.FixedZone("诺福克岛标准时间", 11.5*3600) CHAST = time.FixedZone("查塔姆群岛标准时间", 12*3600*45/60) PSTC = time.FixedZone("太平洋标准时间C", 13*3600) PSTD = time.FixedZone("太平洋标准时间D", 10*3600) ) var AreaListMap = make(map[string]*time.Location, 20) var NtpServerIP = []string{"cn.pool.ntp.org", "2.cn.pool.ntp.org", "3.cn.pool.ntp.org", "0.cn.pool.ntp.org", "1.cn.pool.ntp.org", "tw.pool.ntp.org", "0.tw.pool.ntp.org", "1.tw.pool.ntp.org", "2.tw.pool.ntp.org", "3.tw.pool.ntp.org"} const ( //NTP_SERVER_IP = "cn.pool.ntp.org" NTP_PORT_STR = "123" NTP_PCK_LEN = 48 LI = 0 VN = 3 MODE = 3 STRATUM = 0 POLL = 4 PREC = -6 JAN_1970 = 0x83aa7e80 ) 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_ ntp_time transmit_timestamp ntp_time } type Time struct { wYear uint16 wMonth uint16 wDayofWeek uint16 wDay uint16 wHour uint16 wMinute uint16 wSecond uint16 wMillisecond uint16 } var protocol []byte func construct_packet() ([]byte, int) { reqData := make([]byte, NTP_PCK_LEN) head := (LI << 30) | (VN << 27) | (MODE << 24) | (STRATUM << 16) | (POLL << 8) | (PREC & 0xff) binary.BigEndian.PutUint32(reqData[0:4], uint32(head)) 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)) timeOri := JAN_1970 + time.Now().Unix() binary.BigEndian.PutUint32(reqData[40:44], uint32(timeOri)) binary.BigEndian.PutUint32(reqData[44:48], uint32(nTPFRAC(timeOri))) return reqData, NTP_PCK_LEN } func NtpSet(Localtion string) (time.Time, error) { Local := strings.ToUpper(Localtion) listMap() area, _ := AreaListMap[Local] protocol = make([]byte, 32) for _, ntpServerIP := range NtpServerIP { udpAddr, err := net.ResolveUDPAddr("udp", ntpServerIP+":"+NTP_PORT_STR) if nil != err { log.Println(err.Error()) return time.Now(), err } conn, err := net.DialUDP("udp", nil, udpAddr) if nil != err { log.Println(err.Error()) return time.Now(), err } data, _ := construct_packet() conn.SetWriteDeadline(time.Now().Add(3 * time.Second)) _, err = conn.Write(data) if nil != err { log.Println(err.Error()) return time.Now(), err } recvBody := make([]byte, 4096) conn.SetReadDeadline(time.Now().Add(3 * time.Second)) _, _, err = conn.ReadFromUDP(recvBody) if nil != err { continue } else { 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])))) timestamp := int64(dataStru.transmit_timestamp.coarse) time := time.Unix(timestamp, 0) time = time.UTC() localTime := time.In(area) return localTime, nil } } return time.Now(), nil } func listMap() { AreaListMap["IDL"] = IDL AreaListMap["MIT"] = MIT AreaListMap["HST"] = HST AreaListMap["MSIT"] = MSIT AreaListMap["AKST"] = AKST AreaListMap["PSTA"] = PSTA AreaListMap["MST"] = MST AreaListMap["CST"] = CST AreaListMap["EST"] = EST AreaListMap["AST"] = AST AreaListMap["SAT"] = SAT AreaListMap["BRT"] = BRT AreaListMap["GMT"] = GMT AreaListMap["CET"] = CET AreaListMap["EET"] = EET AreaListMap["MSK"] = MSK AreaListMap["IRT"] = IRT AreaListMap["META"] = META AreaListMap["AFT"] = AFT AreaListMap["METB"] = METB AreaListMap["IDT"] = IDT AreaListMap["NPT"] = NPT AreaListMap["BHT"] = BHT AreaListMap["MRT"] = MRT AreaListMap["EMST"] = EMST AreaListMap["EAT"] = EAT AreaListMap["KRT"] = KRT AreaListMap["FET"] = FET AreaListMap["ACST"] = ACST AreaListMap["AEST"] = AEST AreaListMap["FAST"] = FAST AreaListMap["VTT"] = VTT AreaListMap["NFT"] = NFT AreaListMap["CHAST"] = CHAST AreaListMap["PSTC"] = PSTC AreaListMap["PSTD"] = PSTD } func SetSymTime(tm time.Time) error { strMonth := tm.Month().String() months := []string{"January", " February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", } intMonth := 0 for monthNumber, value := range months { if value == strMonth { intMonth = monthNumber + 1 break } } if runtime.GOOS == "windows" { time := strconv.Itoa(tm.Hour()) + ":" + strconv.Itoa(tm.Minute()) + ":" + strconv.Itoa(tm.Second()) cmd := exec.Command("cmd", "/C", "time", time) if err := cmd.Run(); err != nil { return err } date := strconv.Itoa(tm.Year()) + "-" + strconv.Itoa(intMonth) + "-" + strconv.Itoa(tm.Day()) cmd = exec.Command("cmd", "/C", "date", date) if err := cmd.Run(); err != nil { return err } return nil } else { commandName := "date" time := strconv.Itoa(tm.Hour()) + ":" + strconv.Itoa(tm.Minute()) + ":" + strconv.Itoa(tm.Second()) date := strconv.Itoa(tm.Year()) + "/" + strconv.Itoa(intMonth) + "/" + strconv.Itoa(tm.Day()) + " " + time cmd := exec.Command(commandName, date) err := cmd.Run() if err != nil { return err } return nil } } ```

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

5612 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传