从github 中找到的一份代码进行的修改
板卡是0区,手动加了8个时区
#include <iostream>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#define NTP_TIMESTAMP_DELTA 2208988800ull
#define LI(packet) \
(uint8_t)((packet.li_vn_mode & 0xC0) >> 6) // (li & 11 000 000) >> 6
#define VN(packet) \
(uint8_t)((packet.li_vn_mode & 0x38) >> 3) // (vn & 00 111 000) >> 3
#define MODE(packet) \
(uint8_t)((packet.li_vn_mode & 0x07) >> 0) // (mode & 00 000 111) >> 0
void error(const char *msg) {
perror(msg); // Print the error message to stderr.
exit(0); // Quit the process.
}
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("%s [ ntp server]\n", argv[0]);
return 0;
}
int sockfd, n; // Socket file descriptor and the n return result from
// writing/reading from the socket.
int portno = 123; // NTP UDP port number.
const char *host_name = argv[1]; // NTP server host-name.
std::cout << "NTP: " << host_name << std::endl;
// Structure that defines the 48 byte NTP packet protocol.
typedef struct {
uint8_t li_vn_mode; // Eight bits. li, vn, and mode.
// li. Two bits. Leap indicator.
// vn. Three bits. Version number of the protocol.
// mode. Three bits. Client will pick mode 3 for client.
uint8_t stratum; // Eight bits. Stratum level of the local clock.
uint8_t poll; // Eight bits. Maximum interval between successive messages.
uint8_t precision; // Eight bits. Precision of the local clock.
uint32_t rootDelay; // 32 bits. Total round trip delay time.
uint32_t
rootDispersion; // 32 bits. Max error aloud from primary clock source.
uint32_t refId; // 32 bits. Reference clock identifier.
uint32_t refTm_s; // 32 bits. Reference time-stamp seconds.
uint32_t refTm_f; // 32 bits. Reference time-stamp fraction of a second.
uint32_t origTm_s; // 32 bits. Originate time-stamp seconds.
uint32_t origTm_f; // 32 bits. Originate time-stamp fraction of a second.
uint32_t rxTm_s; // 32 bits. Received time-stamp seconds.
uint32_t rxTm_f; // 32 bits. Received time-stamp fraction of a second.
uint32_t txTm_s; // 32 bits and the most important field the client cares
// about. Transmit time-stamp seconds.
uint32_t txTm_f; // 32 bits. Transmit time-stamp fraction of a second.
} ntp_packet; // Total: 384 bits or 48 bytes.
// Create and zero out the packet. All 48 bytes worth.
ntp_packet packet = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
memset(&packet, 0, sizeof(ntp_packet));
// Set the first byte's bits to 00,011,011 for li = 0, vn = 3, and mode = 3.
// The rest will be left set to zero.
*((char *)&packet + 0) =
0x1b; // Represents 27 in base 10 or 00011011 in base 2.
// Create a UDP socket, convert the host-name to an IP address, set the port
// number, connect to the server, send the packet, and then read in the return
// packet.
struct sockaddr_in serv_addr; // Server address data structure.
struct hostent *server; // Server data structure.
sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Create a UDP socket.
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(host_name); // Convert URL to IP.
if (server == NULL)
error("ERROR, no such host");
// Zero out the server address structure.
bzero((char *)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
// Copy the server's IP address to the server address structure.
bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr,
server->h_length);
// Convert the port number integer to network big-endian style and save it to
// the server address structure.
serv_addr.sin_port = htons(portno);
// Call up the server using its IP address and port number.
if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
error("ERROR connecting");
// Send it the NTP packet it wants. If n == -1, it failed.
n = write(sockfd, (char *)&packet, sizeof(ntp_packet));
if (n < 0)
error("ERROR writing to socket");
// Wait and receive the packet back from the server. If n == -1, it failed.
n = read(sockfd, (char *)&packet, sizeof(ntp_packet));
if (n < 0)
error("ERROR reading from socket");
// These two fields contain the time-stamp seconds as the packet left the NTP
// server. The number of seconds correspond to the seconds passed since 1900.
// ntohl() converts the bit/byte order from the network's to host's
// "endianness".
packet.txTm_s = ntohl(packet.txTm_s); // Time-stamp seconds.
packet.txTm_f = ntohl(packet.txTm_f); // Time-stamp fraction of a second.
// Extract the 32 bits that represent the time-stamp seconds (since NTP epoch)
// from when the packet left the server. Subtract 70 years worth of seconds
// from the seconds since 1900. This leaves the seconds since the UNIX epoch
// of 1970.
// (1900)------------------(1970)**************************************(Time
// Packet Left the Server)
time_t txTm = (time_t)(packet.txTm_s - NTP_TIMESTAMP_DELTA);
// Print the time we got from the server, accounting for local timezone and
// conversion from UTC time.
struct timeval tv = {tv.tv_sec = txTm + 8 * 3600};
settimeofday(&tv, NULL);
txTm+=8*3600;
std::cout << "date:" << ctime(&txTm) << std::endl;
return 0;
}