【问题标题】:Read most recent UDP packet by disabling SO_RCVBUF in Java DatagramSocket?通过在 Java DatagramSocket 中禁用 SO_RCVBUF 来读取最新的 UDP 数据包?
【发布时间】:2012-07-14 19:53:00
【问题描述】:

我需要读取最近传入的 UDP 数据包,无论读取之间丢弃的数据包如何。传入数据包的传入速度比最大应用程序处理速度快 3 倍。为了实现这一点,我使用 Java 的 DatagramSocket 类的 setReceiveBufferSize(int size)SO_RCVBUF 设置为与我预期的数据包相同的大小(以字节为单位)。

但是,在我得到最近的数据包之前仍然有 3 个数据包延迟(如果传入速率是接收速率的 10 倍,则有 10 个数据包延迟)。这表明SO_RCVBUF 不仅仅包含最新的数据包。

首先,setReceiveBufferSize(int size) 的单位是字节吗? javadocs 中没有明确说明。其次,有没有办法禁用SO_RCVBUF,以便我只接收最新传入的数据包?例如,零是该函数的非法参数,但理论上我可以将接收缓冲区大小设置为一。

【问题讨论】:

  • 好吧,记住套接字保存的是最旧的数据,而不是最新的。如果一个数据包到达套接字,它将被缓冲,直到您读取它 - 您无法更改该行为。 (如果套接字缓冲区没有空间,新的数据包将被丢弃)
  • 啊,谢谢,我不知道。有什么方法可以在读取之前清除 SO_RCVBUF?

标签: java sockets networking udp


【解决方案1】:

这看起来是个不寻常的问题;)

我建议将您的应用程序拆分为单独的线程:

  • 接收者(最少的工作,没有解析/等)
    • 处理传入的数据包并将最后读取的对象放入异步变量中
  • 处理(根据你写的,看起来这需要很长时间)
    • 从异步空间读取对象,并处理它(不要忘记忽略前面的)

如果你需要破解 SO_RCVBUF 之类的东西,我认为你应该更接近使用 C/C++ 的 io 处理子系统

【讨论】:

  • 为什么?像 SO_RCVBUF 这样的大多数东西都可以从 Java 中完美破解。
  • 是的,它可以,但我认为你不应该遇到他们的问题。
【解决方案2】:

你做错事了。将接收缓冲区设置得尽可能大。以 512k 为例。将其设置为低只会增加丢包的可能性。要么加快接收代码的速度,要么减慢发送代码的速度。发送无法接收的数据包是没有意义的。

【讨论】:

  • 你读过这个问题吗?如果我不关心丢弃数据包,增加缓冲区大小对我没有帮助。理想情况下,我将没有缓冲区,以便接收功能直接从电线中拉出。
  • 你看答案了吗?减小缓冲区大小也无济于事。最近的数据包是那些将被丢弃的数据包。如果您尝试读取它们,则必须在缓冲区中留出足够的空间,这意味着增加它,并尽可能快地读取它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-16
  • 1970-01-01
  • 2015-11-26
相关资源
最近更新 更多