2016-04-24 62 views
0

我有一個客戶端和服務器Java OIS卡在readObject ..如何解鎖?

服務器 - 提供餅乾

客戶端(S) - 請求Cookie,然後打印它們一次交付。

我知道OIS被阻塞,直到輸出流被寫入並刷新,但我不確定這意味着什麼?我在寫請求之後嘗試調用flush(),但那不起作用。

第二次OIS#readObject被調用後,它卡住了。

這裏是我的代碼:

public class CookieServer { 

public static void main(String[] args) { 
    ServerSocket serverSocket = null; 
    try { 
     serverSocket = new ServerSocket(4444); 
    } catch(IOException e) { 

    } 

    while(true) { 
     try(
       Socket clientSocket = serverSocket.accept(); 
       ObjectOutputStream out = new ObjectOutputStream(clientSocket.getOutputStream()); 
       ObjectInputStream in = new ObjectInputStream(clientSocket.getInputStream()); 
     ) { 
      Object inObject; 
      while((inObject = in.readObject()) != null) { 
       if(inObject instanceof String) { 
        if (((String) inObject).equalsIgnoreCase("Give Me Two Random Cookies")) { 
         out.writeObject(new Cookie("Chocalate Chip")); 
         out.flush(); 
         out.writeObject(new Cookie("blueberry Chip")); 
         out.flush(); 
        } 
       } 
      } 
     } catch(Exception e) { 

     } 
     sleep(1000); 
    } 
} 


private static void sleep(long amount) { 
    try { 
     Thread.sleep(amount); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 

}

public class CookeClient { 

public static void main(String[] args) { 

    while(true) { 

     try (Socket echoSocket = new Socket("localhost", 4444); 
      ObjectOutputStream out = new ObjectOutputStream(echoSocket.getOutputStream()); 
      ObjectInputStream in = new ObjectInputStream(echoSocket.getInputStream())) { 

      out.writeObject("Give Me Two Random Cookies"); 

      Object inObject; 
      while((inObject = in.readObject()) != null) { // gets stuck here... 
       if(inObject instanceof Cookie) { 
        System.out.println("Received a: " + ((Cookie) inObject).getName() + "cookie"); 
       } 
      } 
     } catch (Exception e) { 

     } 

     sleep(100); 
    } 
} 


private static void sleep(long amount) { 
    try { 
     Thread.sleep(amount); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 

}

public class Cookie implements Serializable{ 

private String name; 
public Cookie(String name) { 
    this.name = name; 
} 

public String getName() { 
    return name; 
} 

}

請幫我,我很失落。

回答

0

當您僅期待兩個響應時,您正在使用循環。這沒有意義。只需撥打readObject()兩次。

注意你的環路不正確。在流結束時,readObject()不返回空值。它拋出EOFException。因此,將null用作循環終止條件是不正確的。任何時候你寫一個null都可以返回null。

當沒有可用數據時,它也不會返回null。它阻止。

+0

它沒有陷入無限循環。 in.readobject是一個阻塞的方法...我把一個system.out.println看看是否是這樣,並且它不是經常打印虛擬打印。 – DJavaMan

+0

你誤會了。我說你的循環寫得不正確,而當你只期望兩個對象時循環是沒有意義的。當數據不可用且連接保持打開狀態時,第三次讀取將被阻止。如果這不是你想要的,不要發行第三次閱讀。 – EJP

+0

我明白了,那只是一個例子。假設我不知道我接收了多少物品,我該怎麼辦?如果我再次調用readObject(不會拋出EOF,因爲它被阻止) – DJavaMan