2013-10-20 76 views
0

我做了一個通過ObjectInputStream從服務器接收數據的Messenger。 我希望能夠檢索/發送可串行化文件,同時還能夠從用戶檢索/發送消息。對通過ObjectInputStream收到的數據進行排序

我無法找到一種很好的方法來在兩種(對象和消息)之間進行排序而不會與消息傳遞發生衝突。我試過使用兩個流爲同一個套接字(數據*流&對象*流),它似乎建立良好,但當我嘗試通過Data *流發送一條消息從服務器到客戶端時,我在我的客戶端上獲得java.net.SocketException: socket closed。 (只有當我發送消息時纔會發生)

有人可以指出我正確的方向,我將如何通過流檢索2種不同類型的信息? (不考慮一個簡單的辦法,我不想要做writeObject("[message]"+input);或廉價把戲像



(EDIT)解決方案:

感謝亞諾什,他一直激勵着我寫這個代碼:')感謝的人

輸入接收器:

protected Object data; 

public synchronized Object receivedData() throws ClassNotFoundException, 
               IOException { 
    data = in.readObject(); 

    if(!(data instanceof String)) { 
     retrieveObject(); 
     data = ""; 
     System.out.println("Object"); 
    } 
    return data; 
} 

與MES刺激線:

ExecutorService pool = Executors.newScheduledThreadPool(1); 

private Runnable receiveData; 
public void receiveData() { 
    receiveData = new Runnable() { 

     public void run() { 
      String input; 
      try { 
       while((input = (String) receivedData()) != null) { 
        if(input.length() > 1) 
         System.out.println(input); 

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

    pool.execute(receiveData); 
} 

如果您有任何改進建議,請讓我知道,我會更新此代碼。

回答

1

您可以創建父類Message,以及子類DataMessageTextMessage

當收到Message時,您可以使用instanceof檢查其基礎類型,並相應地處理它。

這些*Message類可以包裝您想要在其成員變量中的客戶端和服務器之間傳遞的任何對象。 *Message類必須是可序列化的,因此所有成員變量也必須是可序列化的。

例如考慮到這些Message類型:

class Message {} 

class TextMessage extends Message { 
    String text; 
} 

class DataMessage extends Message { 
    User user; 
} 

喜歡,你可以把手收到的消息:

Message message = (Message) in.readObject(); 
if (message instanceof TextMessage) { 
    // do something with ((TextMessage)message).text 
} else if (message instanceof DataMessage) { 
    // do something with ((DataMessage)message).user 
} 
+0

你可以舉個例子嗎?如果我要發送(讓我們說..)User.java從Server - > Client,從服務器發送的對象是用戶,並檢索的對象是用戶。用戶擴展對象,所以我必須做'用戶user =(用戶)in.readObject();',但如果我使用類進行排序,將如何那工作? –

+0

@VinceEmigh查看我更新的帖子。 – janos

+0

可能需要一段時間才能測試出來,但這似乎合乎邏輯。我會嘗試一下,如果它能正常工作,請更新。謝謝:)另外,謝謝你的例子,這就是我的想法 –

1

我希望能夠檢索/發送序列化的文件,同時還能夠從用戶檢索/發送消息。

你可以用ObjectInputStreamObjectOutputStream來做所有的事情。

我找不到與消息傳遞衝突的兩種(對象和消息)之間排序的好方法。

該聲明在您指定'衝突'之前是沒有意義的。

我已經使用了相同的插座兩個流(數據流*對象& *流)

  1. 你不能做到這一點嘗試。在套接字的生命週期中使用相同的流。

  2. 你不需要那樣做。你可以用Data*Stream做任何事情,你可以用Object*Stream,做,因爲Data*Stream實現了Data*PutObject*Stream實現了Object*Put,並且Object*Put延伸了Data*Put

,它似乎建立精細,但當我嘗試從服務器發送消息通過數據流*客戶端,我得到java.net.SocketException異常:插座我的客戶端上關閉。

這意味着封閉流並繼續使用它。這是由於您使用了兩個流而造成的。關閉任何包裝在套接字輸入或輸出流中的流將關閉另一個流和套接字。你不需要這個。

(當我發送郵件只發生右)

只有當你從讀取或寫入到一個已經關閉流發生。

有人可以指出我正確的方向,我將如何通過流檢索2種不同類型的信息?

只需使用Object*Stream的API。 。

(不考慮一個簡單的辦法,我不想要做的writeObject(「[信息]」 +輸入);或任何廉價的把戲一樣,

我不知道爲什麼你認爲這是一個'便宜的技巧',你需要停止做出假設並開始設計

+0

不需要粗魯。你在那裏重複了一遍,並沒有幫助我一點。我沒有遇到任何衝突,因爲衝突很明顯。如果我按照這種方式進行排序,那麼除非我花費更多的里程來消除錯誤,否則用戶可能會在系統中手動引起混淆。 –

+0

在這裏沒有粗魯,你不介意嘗試引入這種不相干的東西。你似乎沒有真正的興趣來澄清你想避免的「衝突」。你聲稱這'無助於你'是明顯錯誤的。我已經告訴過你,你不需要使用兩種類型的流;我提供了一個嚴格的證據,證明爲什麼這樣。我也解釋了爲什麼你遇到了異常。顯然你對爭論更感興趣,而不是解決你的問題。我很抱歉我困擾。 – EJP

+0

1.如果'衝突與問題無關',你爲什麼提到它? 2.如果您很明顯無法在同一個基礎流中使用兩個流,請關閉其中一個流,然後使用另一個流而不發生異常,那麼您爲什麼確實這樣做?來自「簡明英漢詞典」我找到了什麼「不在那裏的幫助」? 3.「Object * Streams」API *是您的問題的答案。如果你要抱怨你在這裏給予的幫助,至少應該努力保持它的合理性。 – EJP

相關問題