首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Linux内核UDP接收时间戳

Linux内核UDP接收时间戳
EN

Stack Overflow用户
提问于 2017-01-23 19:47:57
回答 1查看 8.8K关注 0票数 10

我一直在阅读linux内核的network timestamping文档,有一些东西我不太清楚。

SO_TIMESTAMPNS提供的时间戳是在哪里生成的?在硬件中还是在内核中?如果是这样,那么一旦新数据包的中断被引发,它就会生成吗?

SO_TIMESTAMPING还应允许生成硬件时间戳。是否所有NIC都支持此功能?How How SO_TIMESTAMPING with options SOF_TIMESTAMPING_RX_HARDWARE and SO_TIMESTAMPNS?在这种情况下,硬件时间戳是指系统时钟还是指NIC时钟?在第二种情况下,如何检索NIC时钟来计算已用时间?

EN

回答 1

Stack Overflow用户

发布于 2017-02-14 02:10:55

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

代码语言:javascript
复制
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套接字选项提供了许多不同的标志,其中一些是,

代码语言:javascript
复制
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)都支持此套接字选项。目前,许多以太网卡都支持SO_TIMESTAMPING。为了找出特定的接口驱动程序是否支持SO_TIMESTAMPING,请使用:

代码语言:javascript
复制
ethtool -T ethX // where X corresponds to your particular interface

这将返回ethX支持的用于时间戳的所有套接字属性。

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

代码语言:javascript
复制
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);
      }
}
票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41805687

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档