【问题标题】:TCP client serverTCP客户端服务器
【发布时间】:2011-12-20 01:37:39
【问题描述】:

我有一个关于 TCP 客户端/服务器网络的问题。我正在尝试创建一个聊天应用程序。我的计划是让客户端通过网络发送对话对象(对象具有字符串用户名状态和字符串 currentMessage 状态)。我的问题是,我是否应该在每次发送消息时创建一个新对象?即每次我想发送新消息时调用 Conversation 类构造函数?还是我应该只是更新 currentMessage 状态?我有这个问题,因为目前,我只是更新状态,这就是发生的事情:

currentMessage 状态在客户端更新得很好,但是当我通过网络发送 Conversation 对象并尝试在另一端检索 currentMessage 状态时,我不断获得原始状态值。为什么是这样?服务器一直引用我第一次发送的原始消息值??

PS 我不想发布大量代码,所以我希望有人能大致了解我做错了什么

【问题讨论】:

    标签: java serialization tcp


    【解决方案1】:

    我猜你正在使用 ObjectOutputStream 或类似的东西?

    前段时间我自己也遇到过这个问题。第一次发送时它工作正常,但之后它不会正确更新。

    这是因为流保存了对象状态,如果再次发送它不会更新。 您需要在收到对象后使用reset() 方法使其再次更新。

    【讨论】:

    • 谢谢,是的,我相信这是我需要的解决方案 :)
    【解决方案2】:

    您是否使用 ObjectOutputStream 类来序列化您的 Conversation 对象?如果是这样,它将缓存您已经写入流中的类,因此即使您在客户端更改值,每次写入该对象时,它都会发送指向该对象的指针,从而节省大量时间和带宽。不幸的是,这并不总是你的目标,所以你有两个选择:

    • 重置流。来自 JavaDoc:

    重置将忽略任何已写入 溪流。状态被重置为与新的 ObjectOutputStream 相同。 流中的当前点被标记为重置,因此 相应的 ObjectInputStream 将在同一点重置。 之前写入流的对象不会被称为 已经在流中。它们将再次写入流中。

    您可以阅读有关此here 的精彩文章。

    • 按照您的建议创建对话对象的新实例。

    我个人认为创建新对象而不是在每次写入之前(或之后)重置流更干净,但是如果您处于对象分配相当大并且您只更改一个网络写入之间的几个字段,重置流可能会更好。

    然而,这种优化可能最好推迟到项目后期,那时您可以进行一些真正的分析,看看哪种更适合您。我的建议是选择你最满意的那个,然后继续前进,直到你达到优化的重要性。永远记住,过早的优化是好的编程的祸根! :)

    【讨论】:

    • 嗨,马修,感谢您的回复..是的,我正在使用序列化..最初我的代码每次都发送新对象,但我认为这有点浪费,因此将其更改为仅更新消息状态。所以说如果我更新一个向量而不是一个字符串,这是我最初想要做的,这将如何工作..你看,我想编写一个轮询机制,客户将在其中询问最新消息发布到服务器(这将包含一个字符串向量)..我将如何通过网络发送这个向量?
    • 即,如果我每次创建一个新对象,Vector 每次都会重置为一个新的 Vector。我不希望这样,我希望从发送完整的对话字符串向量服务器回到客户端..我不太确定我是否清楚地理解..
    • 我相信我的问题是:我如何创建一个新对象但保持相同的完全填充向量?这甚至可能吗?谢谢
    • 我不确定我是否完全理解您的问题。您是否有要发送的对象向量?在这种情况下,我会保留相同的向量,向其中添加项目,然后发送每个对象,而不是整个向量。然后,您可以清除 Vector,重新填充它,然后重新遍历它以发送它可能拥有的任何新对象。
    • 快速说明:Vector 已被实现 List 接口(LinkedList、ArrayList 等)的类取代,所有新代码都应使用该类。
    【解决方案3】:

    您可以使用flyweight design pattern.

    基本上,您可以拥有一个始终相同的对象。你将它包裹在另一个对象中。 在您的情况下,您发送的对象每次都是相同的。您唯一更改的是文本。

    虽然我不确定您的代码是如何工作的,但在我看来,(1) 创建一个新对象以每次发送或 (2)创建一个并继续设置不同的文本以发送它(有点像享元)。

    前一种方式,您可以预先分配这些信封的大列表,并在发送消息时一个一个地使用它们。这将提高性能。

    至于你的其他问题,我同意 Matt 和 Hasslam。您发送的内容可能已被缓存,因此您需要刷新它,或者让 Java 知道它已被更改。

    【讨论】:

      猜你喜欢
      • 2013-08-20
      • 2012-01-04
      • 2013-02-17
      • 2012-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多