2013-02-01 25 views
1

在我的實驗,在Java套接字中,必須要求服務器和客戶端聲明OutputStream&InputStream的相反順序嗎?

如果服務器有這樣的:

的ObjectInputStream ObjectInputStream的=新的ObjectInputStream(socket.getInputStream()); ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());

然後客戶端必須採取:

的ObjectOutputStream的ObjectOutputStream =新的ObjectOutputStream(socket.getOutputStream()); ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());

否則,服務器和客戶端都會掛起。

這是什麼原因?有沒有一個正式的API規範,我還沒有找到它?

+0

我會想在試圖寫入任何東西之前嘗試從「InputStream」讀取會導致問題(因爲讀取會阻塞),這意味着如果客戶端和服務器都嘗試從相應的'InputStreams'中讀取相同的你希望使用寫入的線程,那麼你會遇到問題... – MadProgrammer

+0

@MadProgrammer它*確實會導致一個問題。這就是他問的原因。但僅限於對象流,因爲構造分別寫入和讀取標題。 – EJP

+0

@EJP - 錯過了「流」中的「對象」:P - 一些更多的caffine的時間 – MadProgrammer

回答

4

是的。我明白這可能會發生。用於ObjectInputStream構造的Javadoc這樣說:。

「創建一個ObjectInputStream從指定InputStream讀取序列化流報頭從流讀取和驗證此構造方法將阻塞,直到相應ObjectOutputStream寫和衝過頭。「

因此,如果客戶端和服務器構建其ObjectInputStream在他們ObjectOutputStream,那麼這兩個將阻止等待另一端發送的序列化流頭。

請注意,這是發生在對象流級別,而不是套接字或字節流級別。如果您通過套接字進行簡單的字節或字符或「數據」I/O,則不需要擔心流的構建順序。

也不是,如果您在客戶端和服務器端都有單獨的線程來執行讀取和寫入,則這不是問題。所有的東西都是平等的,這可能是一個更好的體系結構,因爲它允許客戶端/服務器通過套接字進行「全雙工」通信。

+0

所以需要在至少其中一個端點首先創建ObjectOutputStream,並且生命作爲規則應該是在兩端首先創建它。 – EJP

+0

@EJP - 是的...但如果客戶端或服務器使用2個線程來構建+讀/構造+寫,那麼你不需要打擾。 –