2011-12-20 229 views
1

我对TCP客户端/服务器网络有疑问。我试图创建一个聊天应用程序。我的计划是让客户端通过网络发送对话对象(对象具有字符串用户名状态和字符串currentMessage状态)。我的问题是,每次我发送消息时,是否应该创建一个新对象?即每次我想发送一条新消息时调用Conversation类的构造函数?或者我应该只是更新currentMessage状态?我有这个问题,因为在那一刻,我有它只是更新状态,会出现以下情况:TCP客户端服务器

的currentMessage状态更新精细的客户端,但是当我在网络上发送的谈话对象,并尝试检索在另一边currentMessage状态我不断获得原始状态值。为什么是这样?服务器不断引用我第一次发送的原始消息值?

PS我不希望发布的代码里姆斯因此,进出口希望有人可能有一个总的想法是什么即时做错了

回答

1

即时猜测你正在使用ObjectOutputStream或类似的东西?

前段时间有这个问题我自己。当你第一次发送它的工作正常,但之后它不正确更新。

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

+0

谢谢,是的,我相信这是我需要的解决方案:) – oggiemc 2011-12-20 19:24:30

0

可以使用flyweight design pattern.

基本上你可以有一个对象,是永远不变的。你把它包装在另一个对象中。 在你的情况下,你发送的对象每次都是一样的。你改变的唯一的东西是文字。

虽然我不知道你的代码是如何工作的,我看它的方式是,(1)创建一个新的对象,每次发送或(2)创建一个并保持设定不同的文本发送在它(这有点像轻量级)。

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

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

1

您是否使用ObjectOutputStream类来序列化您的对话对象?如果是这样,它会缓存你已经写入流的类,所以即使你改变了客户端的值,每次你写这个对象时,它都会发送一个指向这个对象的指针,节省了大量的时间和带宽。不幸的是,这并不总是你的目标,所以你只剩下两个选择:

  • 重置流。根据JavaDoc:

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

您可以阅读关于此here的伟大文章。

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

我个人发现创建新对象比在每次写入之前(或之后)重新设置流更清洁,但是如果您处于对象分配相当大的情况,并且您只改变网络写入之间的一对字段,重置流可能会更好。

然而,这种优化可能是最好的,直到后来在你的项目中,当你可以做一些真正的分析,看看哪些更适合你。我的建议是选择最适合的方式,然后继续前进,直到您达到优化重要的程度。永远记住,不成熟的优化是良好编程的祸根! :)

+0

嗨matthew,谢谢你的回复..是我使用序列化..原来我有我的代码每次发送新的对象,但我认为这是一个有点浪费并将其更改为仅更新消息状态。所以说,如果我更新矢量而不是字符串,这是我最初想要做的,这将如何工作..你看,我想写一个轮询机制,其中客户端将要求最新的消息发布到服务器(这将包括一个字符串向量)..我将如何通过网络发送这个向量? – oggiemc 2011-12-20 15:33:24

+0

即如果我每次创建一个新的对象,每次Vector刚刚重新设置一个新的Vector每次..我不想这样,我想要从服务器发送到客户端的会话字符串的完整向量。 。我不太清楚,如果我明确了解清楚了.. – oggiemc 2011-12-20 17:43:06

+0

我相信我的问题是:我如何创建一个新的对象,但保持相同的完全填充矢量?这甚至有可能吗?谢谢 – oggiemc 2011-12-20 18:11:30