我有一个用Java实现MulticastSocket
的程序,以便执行网络发现。问题是,服务器每隔5秒向特定端口(在我的情况下为4446)发送几个带有序列化ArrayList
活动共享的数据包,然后客户端收到该数据包。但是,如果ArrayList
被修改,服务器会在下次发送时将其发送出去,但是客户端在收到时会收到服务器很久以前发送过的旧包。
以下是一个例子:
ArrayList
有1个元素。
服务器 - >发送 - >等5秒 - >发送包#2 - >等5秒 - > 在时间范围内修改ArrayList
- >发送数据包#3
客户 - >寻找活跃份额 - >接收分组#1 - > 1个元素!好! ...(可以等待无限期的时间 - 此时#2和#3已由服务器发送)
客户 - >寻找活跃份额 - >接收#packet 2 - > 1个元素。 NO。
这就是所有一致性都丢失的地方,因为它应该(理想情况下)收到数据包#3。
有没有办法让客户端始终收到最新发送的数据包?谢谢。
答案 0 :(得分:0)
与UDP一样,多播与TCP不同,无法保证向客户端提供交付或交付顺序。如果您没有获得#3,客户可能会在收到数据之前丢弃数据。
我会仔细检查您对客户端/服务器代码操作的假设。
您是丢失了#3包还是只想在#2之前交付并忽略#2?如果是第二种情况,您将需要编写代码,以便尽快收集所有数据包。一个选项是在循环中收到数据包后立即尝试接收(),超时非常低。这可能意味着调整你的so_timeout,这意味着内核往返,并为每个数据包执行此操作,这将是昂贵的。
更好的方法是让一个不断从套接字读取的线程,并将每个数据包放入另一个处理线程读取的BlockingQueue中。通过这种方式,您不必太在意接收的超时,并且由于它只是消耗,您可以像jvm从套接字中读取数据包一样快地获取数据包。
答案 1 :(得分:0)
这是网络通信中固有的竞争条件。数据源在其先前的报告传输到接收器时更改状态 - 此时您要反转时间并更新已在线路上的数据。我没有找到任何方便的库可以做到这一点,所以我建议你按顺序处理你的数据包:)
这里真正的答案是正确communication protocol。不是TCP或UDP之类的传输,而是您自己的应用程序级协议。虽然看一下TCP state transition diagram的一个很好的例子和灵感,但它表明你可以将一个相当复杂的问题视为一个可管理的状态机。在客户端和服务器端定义状态,定义事件和转换,并相应地编码。