0

我有一个用 Java 实现的程序,MulticastSocket以执行网络发现。ArrayList问题是,服务器每 5 秒向特定端口(在我的情况下为 4446)发送几个带有活动共享序列化的数据包,然后客户端接收到该数据包。但是,如果ArrayList修改了,服务器会在下一次发送时将其发送出去,但客户端在收到时会收到服务器很久以前发送的旧包。

这是一个例子:

ArrayList有 1 个元素。

服务器 -> 发送 -> 等待 5 秒 -> 发送数据包 #2 -> 等待 5 秒 ->在时间范围内修改ArrayList-> 发送数据包 #3

客户端 -> 寻找活动共享 -> 接收数据包 #1 -> 1 个元素!好的!...(可以无限期等待——此时服务器已发送 #2 和 #3)

客户端 -> 查找活动共享 -> 接收 #packet 2 -> 1 个元素。不。

这就是失去所有一致性的地方,因为它应该(理想情况下)接收到数据包#3。

有什么方法可以使客户端始终收到发送的最新数据包?谢谢你。

4

2 回答 2

0

这是网络通信中固有的竞争条件。数据源在其先前的报告传输到接收器时更改状态 - 此时您想要反转时间并更新已经在线的数据。我还没有找到任何方便的库可以做到这一点,所以我建议你按顺序处理你的数据包:)

真正的答案是正确的通信协议。不是 TCP 或 UDP 之类的传输,而是您自己的应用程序级协议。虽然看一下TCP 状态转换图以获得一个很好的示例和启发 - 它表明您可以将一个相当复杂的问题视为一个可管理的状态机。在客户端和服务器端定义状态,定义事件和转换,并相应地编码。

于 2012-06-15T03:01:03.947 回答
0

与 UDP 一样,多播与 TCP 不同,它不能保证向客户端交付或交付顺序。如果您没有得到#3,客户可能会在收到之前丢弃数据。

我会仔细检查您对客户端/服务器代码操作的假设。

您是丢失数据包#3 还是只想在#2 之前发送数据包而忽略#2?如果是第二种情况,您将需要编写代码以便尽快收集所有数据包。一个选项是在循环中接收到数据包后立即尝试接收(),超时时间非常低。这可能意味着调整你的 so_timeout,这意味着内核往返,并且对每个数据包都这样做,会很昂贵。

更好的方法是让一个线程不断地从套接字读取数据,并将每个数据包放入另一个处理线程从中读取的 BlockingQueue 中。通过这种方式,您不必太在意接收超时,并且由于它只是在消耗,您将尽可能快地获取数据包,因为 jvm 可以从套接字读取它。

于 2012-06-15T02:52:52.793 回答