NTP 协议获取网络时间

从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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/602446.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HKT x Microsoft 365 Copilot 助力企业提升工作效率

人工智能&#xff08;AI&#xff09;在工作场所的应用和整合日益增多&#xff0c;更成为塑造未来工作模式的革新趋势之一。AI不仅简化和改进了许多任务和流程&#xff0c;还为协作、沟通和创新开辟了新的机遇。不久前&#xff0c;微软新推出AI驱动的生成式生产力工具— Microso…

【Elasticsearch运维系列】Elasticsearch7.12.1启动指定版本JDK:你学废了吗?

一、背景 一套生ES集群&#xff0c;版本为7.12.1&#xff0c;近期频繁告警&#xff0c;频繁出现索引分片异常&#xff0c;索引状态异常&#xff0c;导致应用无法正常写入ES&#xff0c;另外&#xff0c;也经常出现节点掉问题。通过分析相关ES日志&#xff0c;显示和当前JAVA G…

【LAMMPS学习】八、基础知识(5.8)LAMMPS 中热化 Drude 振荡器教程

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语&#xff0c;以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…

DDD架构学习

文章目录 领域建模事件风暴四色建模法 DDD名称解析领域子域核心域通用域支撑域限界上下文战术设计实体值对象聚合和聚合根工厂资源库领域服务领域事件 DDD代码的分层名词解析实体值对象聚合根领域服务领域事件 VO&DTO&DO&PO博客 领域建模 领域驱动设计的核心在于领…

【设计模式】——专栏概述

&#x1f4bb;博主现有专栏&#xff1a; C51单片机&#xff08;STC89C516&#xff09;&#xff0c;c语言&#xff0c;c&#xff0c;离散数学&#xff0c;算法设计与分析&#xff0c;数据结构&#xff0c;Python&#xff0c;Java基础&#xff0c;MySQL&#xff0c;linux&#xf…

智慧校园与学生成长

当时间追溯到2018年&#xff0c;技术的前进已经逾越了人们的幻想&#xff0c;很多先进的设备也投入到了大众的日子中去&#xff0c;为信息化的推进带来了全新的改动。与此同时&#xff0c;校园也不甘落后&#xff0c;将教育与信息化得到一个完美的融合&#xff0c;为学生的未来…

想要买到心仪的旋转式孔板流量计吗?

选择旋转式孔板流量计可不能云里雾里的乱选择呀&#xff0c;煤矿对产品质量要求很严格的。所以我们要先了解产品的再决定才是对的选择。 旋转式孔板流量计技术参数【1--5--9】 规格&#xff1a;DN15&#xff5e;DN1000 孔径比(βd/D)&#xff1a;β0&#xff0e;2—0&#xff…

Web前端三大主流框架是什么?

Web前端开发领域的三大主流框架分别是Angular、React和Vue.js。它们在Web开发领域中占据着重要的地位&#xff0c;各自拥有独特的特点和优势。 Angular Angular是一个由Google开发的前端框架&#xff0c;最初版本称为AngularJS&#xff0c;后来升级为Angular。它是一个完整的…

MySQL迁移data目录

MYSQL数据库有时候安装好了&#xff0c;想移动一下data目录&#xff0c;但是又不想重新安装一下&#xff0c;就只能想办法把这个目录迁移一下。 先找到my.ini配置文件&#xff0c;可以全局搜索一下&#xff0c; 找到之后&#xff0c;把这个地方修改一下&#xff0c;就把data目…

IP协议全解析:网络层通信的基石

⭐小白苦学IT的博客主页⭐ ⭐初学者必看&#xff1a;Linux操作系统入门⭐ ⭐代码仓库&#xff1a;Linux代码仓库⭐ ❤关注我一起讨论和学习Linux系统❤ 前言 在数字化时代的浪潮中&#xff0c;网络通信无处不在&#xff0c;它连接着世界的每一个角落&#xff0c;承载着信息的高…

评估Transitions

Stateflow使用图表中的转换从一种OR状态移动到另一种OR状态。对于图表执行的输入和执行工作流,Stateflow评估转换以确定它们是否有效。有效转换是条件标签为true且路径以状态结束的转换。如果转换有效,则Stateflow将从源状态退出并进入目标状态。 评估Transitions的工作流 T…

Java八股文3

3.垃圾回收 1.对象什么时候可以被垃圾器回收 1.垃圾回收的概念 为了让程序员更专注于代码的实现&#xff0c;而不用过多的考虑内存释放的问题&#xff0c;所以&#xff0c; 在Java语言中&#xff0c;有了自动的垃圾回收机制&#xff0c;也就是我们熟悉的GC(Garbage Collection)…

代码随想录算法训练营第四十二天| 01背包问题理论基础,416. 分割等和子集

理论基础&#xff1a; 带你学透0-1背包问题&#xff01;| 关于背包问题&#xff0c;你不清楚的地方&#xff0c;这里都讲了&#xff01;| 动态规划经典问题 | 数据结构与算法_哔哩哔哩_bilibili很多同学对背包问题的理解程度都处于一种黑盒的状态&#xff0c;及时这道题目在力…

WebDAV之π-Disk派盘 + 溯记

“溯记”是一款提供丰富功能的时间轴日记应用,旨在帮助用户记录生活中的碎片化想法和事件,并提供便捷的回顾和管理功能。根据您提供的描述,这款应用具有丰富的特性,包括时间轴浏览、多媒体支持、实时存储、模糊搜索、日历视图、故事关联和随机回溯。这些功能将帮助用户记录…

C++奇迹之旅:string类对象的容量操作

文章目录 &#x1f4dd; string类的常用接口&#x1f309; string类对象的容量操作&#x1f320;size&#x1f320;length&#x1f320;capacity&#x1f320;clear&#x1f320;empty&#x1f320;reserve&#x1f309;resize &#x1f6a9;总结 &#x1f4dd; string类的常用…

vue导出大量数据的表格方法

我目前的项目导出4万7数据没问题 先安装 npm install -S file-saver npm install xlsx0.16.0 -S npm install -D script-loader 我使用的版本是"file-saver": “^2.0.5”, “xlsx”: “^0.16.0” 新建Export2Excel.js //Export2Excel.js /* eslint-disable */ requ…

直播产品实习生实习报告,笔灵AI生成模版分享

实习体验报告&#xff1a;直播产品实习生 如果有不同的岗位需要写的话可以去笔灵生成一下 网址&#xff1a;https://ibiling.cn/scene/inex?fromcsdnsx 一、实习背景我是XXX&#xff0c;作为一名直播产品实习生&#xff0c;我在XX公司进行了为期X个月的实习。在这段时间里&…

bfs之八数码

文章目录 八数码解题思路图解举例算法思路 代码CPP代码Java代码 八数码 在一个 33的网格中&#xff0c;1∼8这 8个数字和一个 x 恰好不重不漏地分布在这 33 的网格中。 例如&#xff1a; 1 2 3 x 4 6 7 5 8在游戏过程中&#xff0c;可以把 x 与其上、下、左、右四个方向之一…

【微机原理及接口技术】8086/8088系统时序和微机总线

【微机原理及接口技术】8086/8088系统时序和微机总线 文章目录 【微机原理及接口技术】8086/8088系统时序和微机总线前言一、8086/8088引脚信号和工作模式1.8088 的两种组态模式2.最小组态的引脚信号3.最小组态的总线形成4.最大组态的总线形成 二、8086/8088典型时序1.三种周期…

【工具】Office/WPS 插件|AI 赋能自动化生成 PPT 插件测评 —— 必优科技 ChatPPT

本文参加百度的有奖征文活动&#xff0c;更主要的也是借此机会去体验一下 AI 生成 PPT 的产品的现状&#xff0c;因此本文是设身处地从用户的角度去体验、使用这个产品&#xff0c;并反馈最真实的建议和意见&#xff0c;除了明确该产品的优点之外&#xff0c;也发现了不少缺陷和…
最新文章