通过套接字文件描述符上的ioctl调用获取数据包时间戳 [英] Obtain packet timestamp through ioctl call on socket file descriptor

查看:260
本文介绍了通过套接字文件描述符上的ioctl调用获取数据包时间戳的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在运行运行嵌入式Linux的系统。我正在尝试从套接字上接收到的流中获取数据包时间戳。

I'm working on a system running embedded linux. I'm trying to obtain the packet timestamp from a stream I'm receiving on a socket.

创建套接字后,请执行以下操作:

After creating the socket, I do the following:

if (fd != -1) {
    int enabled = 1;
    setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP, &enabled, sizeof(enabled);
}

在我绑定套接字之后,套接字的类型为SOCK_STREAM。通过调用函数 recv(fd,buf,size,0)。现在为了获取接收到的数据的时间戳,我目前正在尝试以下操作:

After that I bind the socket, the socket is of type SOCK_STREAM. I successfully receive data on the socket, by calling the function recv(fd, buf, size, 0). Now in order to obtain the timestamp of the received data, I'm currently trying the following:

ret = recv(fd, buf, size, 0);
if (ret > 0) {
    struct timeval tv_ioctl;
    tv_ioctl.tv_sec = 0;
    tv_ioctl.tv_usec = 0;
    int error = ioctl(fd, SO_TIMESTAMP, &tv_ioctl);
    printf("%ld.%ld - error = %d", (long int)tv_ioctl.tv_sec, 
            (long int)tv_ioctl.tv_usec, error);
}

printf语句始终如下:

The output of the printf statement is always the following:



0.0错误= -1

0.0 error = -1


错误= -1表示表示ioctl调用失败。我已经使用 getsockopt 执行了一个测试,以检查是否设置了SO_TIMESTAMP选项, getsockopt 为选项SO_TIMESTAMP返回了0因此它似乎设置正确。我在这里有点迷茫,如何进一步调查为什么ioctl调用似乎失败了?

The error = -1 indicates that the ioctl call has failed. I've performed a test with getsockopt to check if the SO_TIMESTAMP option is set, getsockopt returns 0 for the option SO_TIMESTAMP so it seems correctly set. I'm a bit lost here, how can I further investigate why the ioctl call seems to be failing?

推荐答案

检索套接字上的最新时间戳为 SIOCGSTAMP ; SO_TIMESTAMP 是套接字选项,而不是ioctl。您的代码应为:

The ioctl to retrieve the most recent timestamp on the socket is SIOCGSTAMP; SO_TIMESTAMP is a socket option, not an ioctl. Your code should read:

int error = ioctl(fd, SIOCGSTAMP, &tv_ioctl);
                      ^^^^^^^^^^

检索时间戳的另一种方法是将 recv 更改为 recvmmsg 并从辅助数据中提取时间戳。这样效率更高,因为它涉及较少的系统调用(套接字读取和时间戳);

The alternate method to retrieve timestamps is to change recv to recvmmsg and extract the timestamp from the ancillary data. This is more efficient as it involves fewer system calls (Socket reading and timestamps); the ioctl is simpler, though.

请注意,SIOCGSTAMP和SO_TIMESTAMP是互斥的-如果要使用SIOCGSTAMP,则应禁用 (启用 = 0 )。这是因为SO_TIMESTAMP指示内核通过 recvmmsg 辅助数据而不是通过SIOCGSTAMP提供时间戳。

Note that SIOCGSTAMP and SO_TIMESTAMP are mutually exclusive - if you're going to use SIOCGSTAMP you should disable SO_TIMESTAMP (with enabled = 0). This is because SO_TIMESTAMP directs the kernel to make the timestamp available via recvmmsg ancillary data instead of via SIOCGSTAMP.

这篇关于通过套接字文件描述符上的ioctl调用获取数据包时间戳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆