当前位置:  开发笔记 > 运维 > 正文

Linux内核UDP接收时间戳

如何解决《Linux内核UDP接收时间戳》经验,为你挑选了1个好方法。

我一直在阅读linux内核的网络时间戳文档,有些东西我不清楚.

SO_TIMESTAMPNS生成的时间戳在哪里?在硬件或内核中?如果是这样的话,一旦新数据包的中断被提出就会被调整?

SO_TIMESTAMPING还应该允许生成硬件时间戳.所有NIC都支持这个吗?如何SO_TIMESTAMPING选择SOF_TIMESTAMPING_RX_HARDWARE and SO_TIMESTAMPNS?在这种情况下,硬件时间戳是指系统时钟还是NIC时钟?在第二种情况下如何检索NIC时钟来计算经过的时间?



1> 小智..:

用于软件时间戳的套接字属性是SO_TIMESTAMPNS.此套接字属性返回系统时钟的时间.它不是在硬件中生成的,而是在软件中处理中断时系统时间的快照.我们可以通过辅助数据(CMSG)访问此时间戳,该辅助数据不属于套接字有效负载,使用:

int level, type;
struct cmsghdr *cm;
struct timespec *ts = NULL;
for (cm = CMSG_FIRSTHDR(&msg); cm != NULL; cm = CMSG_NXTHDR(&msg, cm))
{
    level = cm->cmsg_level;
    type  = cm->cmsg_type;
    if (SOL_SOCKET == level && SO_TIMESTAMPNS == type) {
        ts = (struct timespec *) CMSG_DATA(cm);
        printf("SW TIMESTAMP %ld.%09ld\n", (long)ts[0].tv_sec, (long)ts[0].tv_nsec);
    }
}

SO_TIMESTAMPING套接字选项提供了许多不同的标志,其中一些是,

SOF_TIMESTAMPING_TX_HARDWARE // Transmit timestamp generated in hardware by NIC clock
SOF_TIMESTAMPING_RX_HARDWARE // Receive  timestamp generated in hardware by NIC clock
SOF_TIMESTAMPING_TX_SOFTWARE // Transmit timestamp generated in kernel driver by NIC clock
SOF_TIMESTAMPING_RX_SOFTWARE // Receive  timestamp generated in kernel driver by NIC clock

所有网络接口卡(NIC)均不支持此套接字选项.目前,许多以太网NIC支持SO_TIMESTAMPING.要查找特定接口驱动程序是否支持SO_TIMESTAMPING,请使用:

ethtool -T ethX // where X corresponds to your particular interface

这将返回ethX支持的所有套接字属性以进行时间戳.

要使用特定NIC提供的硬件时间戳功能,请使用以下代码:

int flags;
flags   = SOF_TIMESTAMPING_TX_HARDWARE
            | SOF_TIMESTAMPING_RX_HARDWARE 
            | SOF_TIMESTAMPING_TX_SOFTWARE
            | SOF_TIMESTAMPING_RX_SOFTWARE 
            | SOF_TIMESTAMPING_RAW_HARDWARE;
    if (setsockopt(sd, SOL_SOCKET, SO_TIMESTAMPING, &flags, sizeof(flags)) < 0)
        printf("ERROR: setsockopt SO_TIMESTAMPING\n");

int level, type;
struct cmsghdr *cm;
struct timespec *ts = NULL;
for (cm = CMSG_FIRSTHDR(&msg); cm != NULL; cm = CMSG_NXTHDR(&msg, cm))
{
     if (SOL_SOCKET == level && SO_TIMESTAMPING == type) {
        ts = (struct timespec *) CMSG_DATA(cm);
        printf("HW TIMESTAMP %ld.%09ld\n", (long)ts[2].tv_sec, (long)ts[2].tv_nsec);
      }
}

推荐阅读
pan2502851807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有