首先,一些上下文来解释我为什么选择"UDP采样"路径:
我想在一段未知的时间内快速生成数据.我想要采样的数据是在另一台机器上,而不是消耗数据的机器.我在两者之间有专用的以太网连接,因此带宽不是问题.我遇到的问题是消耗数据的机器比生成数据的机器慢得多.一个附加的约束是,虽然我没有得到所有样本(它们只是样本),但我必须得到最后一个样本.
我的第一个解决方案是让数据生成器为每个生成的样本发送一个UDP数据报,让数据使用者尝试获取它可能的样本,并在UDP套接字已满时让其他人被套接字层丢弃.这个解决方案的问题是,当新的UDP数据报到达并且套接字已满时,新数据报将被丢弃而不是旧数据报.因此,我没有保证拥有最后一个!
我的问题是:有没有办法让UDP套接字在新到达时替换旧的数据报?
接收器目前是一台Linux机器,但是未来可能会改变另一种类似unix的操作系统(Windows可能会实现BSD套接字,但不太可能)
理想的解决方案会使用广泛的机制(如setsockopt()) s)工作.
PS:我想到了其他解决方案,但它们更复杂(涉及发件人的大量修改),因此我想首先对我要求的可行性有一个明确的地位!:)
更新:
- 我知道接收机器上的操作系统可以处理网络负载+重新组装发送方生成的流量.它的默认行为是在套接字缓冲区已满时丢弃新的数据报.而且由于接收过程中的处理时间,我知道无论我做什么它都会变满(浪费一半的内存在套接字缓冲区上不是一个选项:)).
- 我真的希望避免让一个辅助进程执行操作系统在数据包分派时可能完成的操作,并浪费资源只是在SHM中复制消息.
- 我看到修改发件人的问题是我可以访问的代码只是一个PleaseSendThisData()函数,它不知道它可能是最后一次在很长一段时间之前被调用,所以我不知道看到任何可行的伎俩...但我愿意接受建议!:)
如果真的没有办法改变BSD套接字中的UDP接收行为,那么......告诉我,我准备接受这个可怕的事实,并且当我回到时,我将开始研究"帮助程序"解决方案它:)
只需将套接字设置为非阻塞,然后循环recv()
直到它返回<0 errno == EAGAIN
.然后处理你得到的最后一个包,冲洗并重复.