2016-11-16 70 views
1

我剛纔遇到了一個奇怪的錯誤。我在玩Serializable對象,我使用了兩個對象,通過Socket連接相互通信。這兩個應用程序是相同的(Peer 2 peer),但有兩個實例正在運行並嘗試進行通信。在Socket.getInputStream之前發送一些東西給SocketInputStream?

這些問題似乎圍繞從套接字InputStream獲得ObjectInputStream。在reader = new ObjectInputSream(cliIn)發生在我的錯誤,我被拋出SocketTimeoutException(這是它自奇怪,我本來預計在read()不是裝飾我流時,下面是我試圖做的事情。

Socket clientSocket; 
clientSocket = new Socket(InetAddress.getByName(aHostIP), aPort); 
clientSocket.setSoTimeout(3000); 

InputStream cliIn = clientSocket.getInputStream(); 
ObjectInputStream reader = null; 
reader = new ObjectInputStream(cliIn); // <--- Error here 
ObjectOutputStream writer; 
writer = new ObjectOutputStream(new BufferedOutputStream(
    clientSocket.getOutputStream() 
)); 

writer.writeObject(new Request(aPort)); 
writer.flush(); 

有什麼奇怪的是,如果我移動ObjectInputStream的創作,直到我曾寫信給OutputStream(此時其他物體會迴應請求)後,再有就是沒有更多的錯誤。

Socket clientSocket; 
clientSocket = new Socket(InetAddress.getByName(aHostIP), aPort); 
clientSocket.setSoTimeout(3000); 

ObjectOutputStream writer; 
writer = new ObjectOutputStream(new BufferedOutputStream(
    clientSocket.getOutputStream() 
)); 

writer.writeObject(new Request(aPort)); 
writer.flush(); 

InputStream cliIn = clientSocket.getInputStream(); 
ObjectInputStream reader = null; 
reader = new ObjectInputStream(cliIn); // <--- No more error 

的其他(響應方)如下所示:

ObjectInputStream in = new ObjectInputStream(aConnection.getInputStream()); 
Object req = in.readObject(); 
SysIO.print("FROM OBJECT! : " + req.toString()); 
SysIO.print("FROM OBJECT! Port: " + ((Request) req).getPort()); 

Request res = new Request(15); 

ObjectOutputStream out = new ObjectOutputStream(
     new BufferedOutputStream(aConnection.getOutputStream())); 
out.writeObject(res); 
out.flush(); 

它現在可以工作,但我很想知道這個問題是什麼,以備將來參考。我可以看到它可能很難說清楚,但也許你有進一步調查的一些指針,併發問題,我使用套接字或緩衝區錯誤?

(我已經離開了一些錯誤處理,使其更爲清楚。)

回答

0

答案是在ObjectInputStream documentation

public ObjectInputStream(InputStream in) 
        throws IOException 

創建一個ObjectInputStream中,從指定的InputStream讀取。 從流中讀取序列化流頭並進行驗證。此構造函數將阻塞,直到相應的ObjectOutputStream已寫入並刷新標頭

如果安裝了安全管理器,此構造函數將直接或間接地由覆蓋ObjectInputStream.readFields或ObjectInputStream.readUnshared方法的子類的構造函數調用時檢查「enableSubclassImplementation」SerializablePermission。

參數:

in - 輸入流從

讀拋出:

StreamCorruptedException - 如果該流報頭是不正確

IOException - 如果發生I/O錯誤而閱讀流標頭

SecurityException - 如果不受信任的子類非法重寫安全敏感的方法

NullPointerException - 如果in爲null

在施工期間,流試圖讀取從插座系列化頭,但套接字讀取超時因爲對方還沒有發送任何序列化的對象。

+0

非常感謝您的回答。所以這是讀取引發'SocketTimeoutException'的頭文件?據我所知,無法100%確定緩衝區是否爲空。這樣的行動是必要的還是足夠的,以至於我將輸入和輸出流的開放與服務器相匹配? (建議[這裏](http://stackoverflow.com/a/21075566/2671179)?) –

+0

是的,套接字超時是由於讀取流標題,因爲當時沒有可讀的標題。您的客戶端在服務器發送它的ObjectOutputStream頭之前不能創建ObjectInputStream,這隻有在客戶端先發送它的ObjectOutputStream之後纔會發生。 –

相關問題