2014-11-23 15 views
0

我的項目由2部分組成:服務器端和客戶端。當我開始服務器端一切正常,但是當我開始客戶端不時我得到這個錯誤:Java ObjectOutputStream重置錯誤

java.io.IOException: stream active 
    at java.io.ObjectOutputStream.reset(Unknown Source) 
    at client.side.TcpConnection.sendUpdatedVersion(TcpConnection.java:77) 
    at client.side.Main.sendCharacter(Main.java:167) 
    at client.side.Main.start(Main.java:121) 
    at client.side.Main.main(Main.java:60) 

當我試圖運行這個錯誤發生更加頻繁的其他電腦這個項目。在Java文檔中,我發現了這一點。

Reset may not be called while objects are being serialized. If called inappropriately, an IOException is thrown.

而這正是引發錯誤

void sendUpdatedVersion(CharacterControlData data) { 
     try { 
      ServerMessage msg = new ServerMessage(SEND_MAIN_CHARACTER); 
      msg.setCharacterData(data); 
      oos.writeObject(msg); 
      oos.reset(); 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

我試圖把沖水(),但沒有幫助的功能。有任何想法嗎?此外,在服務器端沒有錯誤。

+0

你想通過reset()調用實現什麼功能? – 2014-11-23 13:26:52

+0

我知道每次創建新對象時,理論上我不需要它,但不知何故,如果我不重置它會發送舊數據。 – master9999 2014-11-23 13:29:00

回答

1

我認爲你誤解了reset()的功能。它重置流以忽略先前寫入到它的任何對象實例。這很明顯不是你想要的,因爲你正在向流發送一個對象,然後立即重置,這是毫無意義的。

它看起來像所有你需要的是一個flush();如果這不足,那麼問題在於接收方。

0

我認爲你很困惑close()和reset()。 使用

oos.close(); 

代替oos.reset();

0

調用reset()是想要做的完全有效的事情。有可能'數據'被重用,或者數據中的某個字段被重用,而第二次他調用sendUpdatedVersion時,該部分不會被髮送。那些抱怨使用無效的人並不準確。現在至於爲什麼你會得到這個錯誤消息

錯誤消息說的是,你不在你的writeObject調用鏈的頂層。 sendUpdatedVersion必須從另一個writeObject調用的方法中調用。

我假設某個對象正在實現一個自定義的writeObject(),並且該方法正在調用此方法。

因此,您必須區分sendUpdatedVersion何時在調用鏈的頂級調用,並且僅在這些情況下使用reset()。

+0

是的,你是對的。我正在使用重複使用的數據。這就是爲什麼我需要重置()。但是我不確定這個錯誤。我太笨了,不能在服務器端關閉流,所以也許這是一個原因..現在看起來它工作的很好。我稍後會檢查其他機器。 – master9999 2014-11-23 15:36:18

+0

這是一個非常有效的做法*除非*你處於'writeObject()'調用的中間,即在一個私有'writeObject()'方法中,當你得到這個異常時, [Javadoc中](https://docs.oracle.com/javase/8/docs/api/java/io/ObjectOutputStream.html#reset--)。 – EJP 2017-03-29 10:06:35