首页 > 解决方案 > recvmsg() 返回“资源暂时不可用”

问题描述

我正在使用 Linux 机器,并且正在发送 UDP 数据包。

我想获取 NIC 上传输数据包的硬件时间戳。我看过其他帖子并设置了适当的标志。

int flag = SOF_TIMESTAMPING_TX_HARDWARE | SOF_TIMESTAMPING_RAW_HARDWARE;

我在用着:

int rc = recvmsg(fd, MSG_ERRQUEUE);

不过,recvmsg()似乎又回来了"Resource temporarily unavailable"。我在等待 50 微秒后调用此函数,然后重试 5 次。我能够使用相同的代码获得硬件时间戳,但现在我遇到了这个问题而没有做任何改变。

关于我应该研究什么可能导致这个问题的任何想法?

标签: clinux

解决方案


linux/Documentation/networking/timestamping.txt中,有关于从错误队列中读取传输时间戳的注释:

2.1.1.5 阻塞读

从错误队列中读取始终是非阻塞操作。要阻止等待时间戳,请使用 poll 或 select。如果错误队列上有任何数据准备好,poll() 将在 pollfd.revents 中返回 POLLERR。无需在 pollfd.events 中传递此标志。该标志在请求时被忽略。另见“人 2 民意调查”。

因此,无论套接字是否处于非阻塞模式,如果错误队列为空,您似乎都会收到指示的错误(即,因为尚未传输数据包,所以时间戳还没有) t 已排队)。

我最好的猜测是,您遇到的情况是,无论出于何种原因(其他传出流量,可能是线路上的争用,等待 ARP 响应),数据包排队等待传输的时间超过 50 微秒,所以您错过了过早放弃的时间戳。我建议以更大的超时时间进行轮询,看看是否能解决问题。


推荐阅读