如何在排队后取消计划用于基于时间的传输的数据包?

如何在排队后取消计划用于基于时间的传输的数据包?

我正在编写一个时间敏感的网络应用程序,该应用程序涉及接收单个以太网帧,然后在精确的1秒延迟后(中间进行一些处理)将数据发送到另一个以太网帧中。

然而,一个特别的症结是我还需要有能力取消如果在该延迟间隔期间收到另一种不同类型的消息,则继续发送数据包。

为了获得精确的 1 秒延迟,我使用了内核的套接字时间戳功能和这个结合基于时间的数据包传输。这两个功能的组合使得可以产生可预测且相当精确的延迟,同时仍然将应用程序保留在用户空间中并且不需要整个系统在实时进程调度程序上运行。

具体来说,我正在创建套接字socket(AF_PACKET, SOCK_RAW, TEST_ETHERTYPE)(真正的应用程序将处理 IPv4,但现在我使用另一种以太类型进行测试),然后设置SO_TIMESTAMPNSSO_TXTIME套接字选项以生成数据包到达时间戳并允许指定传输次。

然后,在主循环中,应用程序将使用 apirecvmsg返回SCM_TIMESTAMPNS控制消息以及接收到的数据包数据,将数据包处理成要发送的数据包,然后使用 api将其入队以使用包含时间戳(恰好在初始接收时间戳之后一秒)的控制消息sendmsg进行传输。SCM_TXTIME

然而,似乎没有任何方法可以在数据包入队后真正“收回”数据包 - 即使使用基于时间的传输,数据包可能会在队列中驻留一段较长的时间。

我知道我可以在我的应用程序中实现我自己的数据包队列,然后仅在数据包非常接近到期时才使用内核调度数据包;无论如何,这甚至可能是避免给内核队列带来压力的正确举措。不管它是如何实现的,在延迟结束时总会有一些非零间隔,无法保证数据包在传输之前被取消。

但如果是仅有的可能从我的应用程序自己的软件队列中取消数据包,那么最坏情况的取消窗口必然会进一步悲观,因为在确保数据包在截止日期之前排队时需要考虑更多的调度不一致。一般来说,必须为该软件队列的不同端管理多个线程,这也变得更加复杂。

简而言之:是否有任何方法可以在已将数据包排入内核队列后取消计划进行基于时间传输的数据包?

相关内容