The original Golang implements the NTP protocol to get the server time

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

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 dedicated port number String */
Ntp_pck_len = 48
LI = 0
VN = 3
MODE = 3
Stratum = 0
POLL = 4
PREC =-6
jan_1970 = 0X83AA7E80/* Time in seconds between 1900/~1970 years */

)

Func Ntpfrac (x Int64) Int64 {
Return (4294* (x) + ((1981 * (x)) >> 11))
}

Func USEC (x Int64) Int64 {
Return ((((x) >>)-759* (((((((((((((((((((x)) +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)
Set the 16-byte header
Head: = (LI << 30) | (VN << 27) | (MODE << 24) | (Stratum << 16) | (POLL << 8) | (PREC & 0xFF)
Binary. Bigendian.putuint32 (Reqdata[0:4], UInt32 (head))
Set root Delay, root dispersion, and 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))

Setting the timestamp section
Timeori: = jan_1970 + time. Now (). Unix ()

Set transmit Timestamp Coarse
Binary. Bigendian.putuint32 (reqdata[40:44], UInt32 (Timeori))
Set 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)

    //waiting to exit
    c: = Make (chan os. Signal, 1)
    signal. Notify (c, OS. Interrupt, OS. Kill)
    <-c
    fmt. Println ("NTP Receive ctrl-c")
}
 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.