【问题标题】:Java network error during file synchronization文件同步期间的 Java 网络错误
【发布时间】:2012-02-21 01:50:35
【问题描述】:

我目前正在研究简单的客户端/服务器文件同步。为此,客户端和服务器遵循一个简单的协议,该协议确定消息发送的顺序。

缩短协议(使用 Object/ByteArrayStreams):

客户端循环:

  1. 发送文件名
  2. 发送文件信息
  3. 发送数据
  4. 等待服务器确认

服务器循环:

  1. 读取文件名
  2. 读取文件信息
  3. 接收数据
  4. 向客户发送确认

重复。

问题是当传输过程中发生错误时协议出现故障,我通常会收到StreamCorruptedExceptions,因为至少一方在期待别的东西。

这是问题的示例情况: 无论出于何种原因,服务器在文件接收 (3) 期间出现故障。现在服务器等待一个文件名。由于错误,客户端到达发送数据的第 3 部分。然后抛出异常,因为服务器需要一个消息对象并且客户端发送字节数据。

解决这个问题的最佳方法是什么?

【问题讨论】:

  • 您使用的是基于 TCP 的协议吗?您可以通过进程内对象直接交换消息来重现此错误吗?你写过自定义的 Externalizable 实现吗?
  • 也许我在使用“协议”这个词时表达了自己的错误。它只是发送文件名之类的消息,使用Java(对象)流的数据,然后是确认消息。我在测试条件下没有遇到这个错误,但在使用过程中可以重现。
  • 从异常看来,您正在使用 ObjectInputStream 和 ObjectOutputStream,而不是像 UDP 这样的“尽力而为”协议。是这样吗?
  • 是的,我正在使用这些 Streams,但它们是通过 TCP 使用的。
  • 文档说您的对象流已损坏。您应该发布一个小的、可编译的、可运行的代码 sn-p 供某人测试。

标签: java error-handling synchronization client-server


【解决方案1】:

一些想法

  • 也许在每个阶段之后发送确认 - 这将更容易控制
  • 来自服务器的 ack 可以发送一个校验和,客户端可以验证事务的完整性并继续前进。 (例如 md5)。
  • 实现一个“无状态”服务器 - 即可以根据您可以在每个事务开始时设置的一些“幻数”(一个标头)来决定在哪个阶段提供服务的服务器。 这样,客户端可以重试任何阶段,服务器将能够做出相应的响应。
  • 您可以扩展标头以包含唯一文件的唯一 ID,这样您就可以并行化整个通信并在多个阶段从多个客户端上传多个文件。

其他想法

  • 如果您想避免问题,而不是解决问题,您可以使用非常有效的库来为您解决问题,而不是重新发明轮子。看看protobuf - 它很难掌握,但效率极高,gson 很容易掌握,但效率较低,或许多其他现成的协议。

【讨论】:

  • 感谢您的回答!我选择了一个无状态服务器,现在它工作得更好了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多