【问题标题】:What structure of data use to communicate via tcp/ip in java?java中通过tcp/ip进行通信的数据结构是什么?
【发布时间】:2011-02-14 12:48:14
【问题描述】:

假设我想在两个使用 TCP 套接字的 java 程序之间发送许多消息。

我认为最方便的方式是发送如下对象:

PrintStream ps = new PrintStream(s.getOutputStream());

ObjectOutputStream oos = new ObjectOutputStream(ps);

  some_kind_of_object_here;

  oos.writeObject(some_kind_of_object_here);

 ps.print(oos);

我要发送,字符串,数字,HashMaps,布尔值 如何使用可以存储所有属性的 fx 1 对象来做到这一点? 我认为 ArrayList 是可序列化的,我们可以把所有东西都放在那里,但这不是优雅的方式。 我想发送不同类型的数据,因为用户可以从服务器可以为它做的各种选项中进行选择。 有什么建议吗?

【问题讨论】:

  • 我的建议:试试看/看看效果如何!
  • 我试过了,问题是我不知道如何读取该对象(我的新类)我可以将它转换为某个相同的类,但 UUID 不一样所以它失败了

标签: java send tcp-ip


【解决方案1】:

您是否考虑过使用 RMI?

如果您需要额外的性能,请坚持使用Serializable 甚至Externalizable

您不需要像 Lists 这样的包装类。当然,您可以构建自己的包装对象,将所有相关数据保存在一起。这样的“应用程序数据单元”将帮助您处理发送实体的正确顺序。只要所有成员都是Serializable,一旦将包装对象放入对象流中,完整的对象图就会自动序列化。

如果您不使用包装类,请确保您要传输的每个对象/类型至少实现 Serializable。然后您必须验证数据发送的顺序是否与您除了数据到达的顺序一致。

【讨论】:

  • 是的,我想使用这 1 个大对象来存储所有信息,但我不知道如何从另一侧读取它,我可以创建具有相同字段但 UUID(或某事)的类像那样)将不匹配
  • Java 会为您完成所有这些工作,如下所示:java2s.com/Code/Java/Network-Protocol/… 不要像示例中那样使用哈希表,而是使用任意类,该类必须存在于两个节点的类路径中。跨度>
  • 还是我看错了?您的问题是您正在创建对象的副本吗?然后使用 RMI 并导出您的对象。
【解决方案2】:

如果您需要保持较小的数据包,您可以使用普通的Object[],在其中放置您想要的任何内容并使用指定数据包类型的枚举,允许您在消息中存储多少和哪些类型的对象。

class Message
{
  Type t;
  Object[] params;
}

当然,在选择如何处理每个数据包时,您必须根据 Type t 进行切换,但由于协议通常是 FSM(这取决于您正在编码的内容),这会很好地工作而不会浪费太多空间或分配不需要时列出。

【讨论】:

  • 如果您想这样做,请改用 Serializable[]。但是我不明白这里的重点。只需使用常规类并将我们的值添加为成员。当您在解组时必须将类型转换回原始类型时,使用此数组/列表只会增加开销。
  • 是的,Serializable 是可以的(但这只是一个约束,它并不真正意味着什么)!在任何情况下,如果您没有具有不同参数/参数类型的多种不同数据包,您都可以像 PartlyCloudy 建议的那样做。
  • 当然有区别。如果将不可序列化的对象放入数组中,它将在编译期间失败。在您的版本中,它会在编组期间失败——这很糟糕。
  • 这不是真的,我在包含数组的 Serializable 类中使用了这种方法。在编组期间不会抛出异常,也不会失败..这就是为什么我说这只是一个约束..
  • 因为您只是将对象放入可序列化的数组中。如果您尝试放入不可序列化的东西,程序仍将编译。但是它会在 rumtime 期间崩溃。
【解决方案3】:

按照您编写代码的方式,您已经可以发送任何 Java 对象。这些对象当然包括“字符串、数字、HashMap、布尔值”。

只需写入 ByteArrayOutputStream:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.write(javaObject);
oos.close();
socket.write(baos.toByteArray())

【讨论】:

  • 不需要 ByteArrayOutputStream,ObjectOutputStream 会自动处理所有这些东西。
  • 我知道如何发送那种对象,但我想在 1 个对象中发送所有这些字符串、数字、HashMap、布尔值,只使用:oos.write(This_1_big_powerfull_object);
【解决方案4】:

大师,您知道您可以通过套接字将任何可序列化对象发送到另一个 JVM,是吗?

如果是这样,最简单的方法是拥有一个包含所有对象的可序列化对象,然后将其转发。对象列表可能是最简单的。然后,您可以在另一端反序列化它,并以您需要的任何方式处理列表中的对象。

我建议您阅读 Java 中的序列化技术,以便了解您可以做的所有智能事情。

http://java.sun.com/javase/7/docs/technotes/guides/serialization/index.html

【讨论】:

  • 这个链接很好,我已经发现那里很有趣,tak
猜你喜欢
  • 1970-01-01
  • 2017-07-12
  • 1970-01-01
  • 1970-01-01
  • 2016-11-25
  • 1970-01-01
  • 1970-01-01
  • 2012-06-29
  • 1970-01-01
相关资源
最近更新 更多