2011-12-20 342 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