C++ 从gettimeofday创建ntp时间戳

C++ 从gettimeofday创建ntp时间戳,c++,c,networking,unix,ntp,C++,C,Networking,Unix,Ntp,我需要使用gettimeofday计算ntp时间戳。下面是我如何通过对方法的评论来完成的。你们看起来不错吧?(减去错误检查)。还有,这里有一个链接 #包括 #包括 常量无符号长历元=2208988800UL;//历元时间和ntp时间之间的差值 常数双NTP刻度分数=4294967295.0;//ntp分数部分的最大值 int main() { 结构时间值电视; uint64 ntp时间; uint64电视ntp; 双电视; gettimeofday(&tv,NULL); tv_ntp=tv.tv

我需要使用gettimeofday计算ntp时间戳。下面是我如何通过对方法的评论来完成的。你们看起来不错吧?(减去错误检查)。还有,这里有一个链接

#包括
#包括
常量无符号长历元=2208988800UL;//历元时间和ntp时间之间的差值
常数双NTP刻度分数=4294967295.0;//ntp分数部分的最大值
int main()
{
结构时间值电视;
uint64 ntp时间;
uint64电视ntp;
双电视;
gettimeofday(&tv,NULL);
tv_ntp=tv.tv_sec+EPOCH;
//将tv_usec转换为几分之一秒
//接下来,我们将这个分数乘以NTP_SCALE_FRAC,表示
//分数的最大值,直到它滚动到1为止。因此,
//.05秒在NTP中表示为(.05*NTP\u刻度\u分数)
tv_usecs=(tv.tv_usec*1e-6)*NTP_比例_分数;
//接下来,我们取tv\u ntp seconds值并将其向左移动32位
//秒在NTP时间戳的正确位置。我认识到此方法具有
//2106年左右使用后有溢出危险
//下一步,我们将tv_usecs转换为uin32_t,并删除分数
//部分

ntp_time=((tv_ntp此处无需使用
uint64_t
)-
无符号长
保证至少64位宽

您也不需要往返于
double
,因为
NTP\u SCALE\u FRAC*1000000
将很容易适应
无符号长时间

EPOCH
应该是
unsigned long
,而不是
unsigned long
,这样与
tv.tv_sec
的相加就不会结束

全部结束:

const unsigned long long EPOCH = 2208988800ULL;
const unsigned long long NTP_SCALE_FRAC = 4294967296ULL;

unsigned long long tv_to_ntp(struct timeval tv)
{
    unsigned long long tv_ntp, tv_usecs;

    tv_ntp = tv.tv_sec + EPOCH;
    tv_usecs = (NTP_SCALE_FRAC * tv.tv_usec) / 1000000UL;

    return (tv_ntp << 32) | tv_usecs;
}
const无符号长历元=2208988800ULL;
常数无符号长NTP_比例=4294967296ULL;
未签名的长-长tv到ntp(结构时间值tv)
{
未签名的长电视ntp,电视usecs;
tv_ntp=tv.tv_sec+EPOCH;
tv_usecs=(NTP_SCALE_FRAC*tv.tv_usecs)/1000000UL;
返回(tv\u ntp
extern uint64\u t tvtontp64(struct timeval*tv){
uint64_t ntpts;
ntpts=((uint64_t)电视->电视秒+220898880U)电视秒*4294.967296);
返回(ntpts);
}
我使用的是4294.967296而不是…5,因为它是总计数的一个比率,需要计算0 每秒4294967296个滴答声或每秒4294.967296个滴答声很容易验证这一点,因为1000000个usec将是溢出[到秒]。滴答声的范围应为0到(1000000-1)

这是一种简化,适合我的目的
唯一的本地IPv6单播地址[RFC4193]

我可能会误解,但长期以来的规范是它至少是64个,但可能更多。我必须对结果(网络字节顺序)进行一些字节交换,所以我想更严格地限制大小。是的,它可能更大。如果需要操纵底层表示(比如说,要将其填充到网络数据包中),则使用
uint64\u t
是合适的,但通常应将其用于处理打包/解包代码本身的网络。Off为1。
NTP\u SCALE\u FRAC
应为
4294967296ULL
,或者最好使用
tv\u usecs=((无符号长-长)我能问一下为什么你要把电视和NTP比例分数相乘吗?对我来说,这似乎是把usec变成了皮秒(*10^6)应该足够了,也许我遗漏了什么?在NTP中,如果我理解正确,分数部分表示为总可能值的分数。因此它不是1:1。例如,如果我在1000个部分中表示1秒,那么有人给我一个以60为基数的0.5秒的值,我必须将其缩放到以1000为基数的0.With NTP,基数是它转换成的32位表示形式。因此1秒=2^32 NTP分数秒。谢谢,我理解这一点。我不清楚的是为什么tv_usecs=(NTP_SCALE_FRAC*tv.tv_usec)/10000000000ul起作用?提升配方中始终等于已知常量值的部分。假设你的奶牛每天产奶200升(常量)。国王税务员要求你每天产奶量的可变百分比。小学教学:百分比*总数/100(100,因为它是%,而不是百万分之一)。今天他想要25%,所以25*200/100=50。敲响了警钟?数学告诉我们,(以基数/基数-10)除以10就是移动小数点。因此(25*200)/100=(25/100)*200=25*(200/100)=50所以常数200/常数100=常数2。因此25*2!!!
const unsigned long long EPOCH = 2208988800ULL;
const unsigned long long NTP_SCALE_FRAC = 4294967296ULL;

unsigned long long tv_to_ntp(struct timeval tv)
{
    unsigned long long tv_ntp, tv_usecs;

    tv_ntp = tv.tv_sec + EPOCH;
    tv_usecs = (NTP_SCALE_FRAC * tv.tv_usec) / 1000000UL;

    return (tv_ntp << 32) | tv_usecs;
}
extern uint64_t tvtontp64(struct timeval *tv) {
    uint64_t ntpts;

    ntpts = (((uint64_t)tv->tv_sec + 2208988800u) << 32) + ((uint32_t)tv->tv_usec * 4294.967296);

    return (ntpts);
}