// 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: %vn",errData) return } fmt.Println("ntp after ResolveTCPAddr.....: ",udpAddr)
conn,err := net.DialUDP("udp",nil,udpAddr) if nil != err { fmt.Printf("ntp net connect error: %vn",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: %vn",err) return } else { fmt.Printf("ntp write len: %vn",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: %vn",err) } else { fmt.Printf("ntp read len: %vn",size) } fmt.Println("ntp after read,remoteAddr: %vn",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) <-c fmt.Println("ntp Receive ctrl-c") } (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|