2011-03-16 84 views
0

我有一個Java客戶端和服務器我試圖寫Junit測試。在我的測試中,我等待服務器和客戶端之間的連接,然後寫一條消息到服務器到客戶端來測試通信。我發現如果我立即執行寫操作,它沒有收到,並且客戶端在BufferedReader.readLine()方法中保持阻塞狀態。如果我在套接字連接和服務器寫入調用之間添加一個半秒的睡眠,那麼一切都可以正常工作。Java套接字讀取未收到連接建立後立即發送寫入

我想弄清楚爲什麼需要睡眠。我知道套接字已經生成,並且在我的waitForConnection()方法返回一個服務器和客戶端已連接的報告之前,在其輸入流周圍封裝了一個bufferedReader。我最好的猜測是,我需要確保在服務器調用write方法之前調用客戶端的readLine方法;但我認爲套接字會自動緩衝輸入並且不立即讀取?

任何人都可以確認(或反駁)我懷疑我必須保證客戶端在服務器調用寫入之前調用readline。如果這是必需的,任何人都可以建議一種方法,即服務器可以檢測客戶端是否準備好接收輸入,而不必實施除TCP握手之外的另一次握手?

編輯:我應該早點說這個,但是失敗的測試是測試一個能否在舊的失敗時重新建立連接。客戶端連接後,我的模擬服務器終止socket/serverSocket,幾秒鐘後重新打開一個新的serverSocket並接受來自客戶端的新連接。客戶端第二次建立連接後,寫入失敗。我以前的測試只是測試連接發生,客戶端收到寫入似乎工作。

感謝

回答

0

你並不需要確保客戶端讀取服務器寫入之前。網絡層將緩衝流量直到消耗完。

確保在服務器上發出消息後在OutputStream上調用flush。否則,直到緩衝區填滿後才能進行實際的網絡呼叫。此外,您使用readLine可能會有問題。也許你不是發行行終止字符?使用更基本的讀取(char [])方法可能會更好。

+0

謝謝你的意見,但我已經確保既沖洗和換行正在做。同花順的東西確實會導致我原來的測試失敗,但那個更容易理解。 – user623257 2011-03-16 15:20:27

-1

如何在單元測試中銷燬服務器套接字?可能是在數據發送之前關閉套接字。

+0

serverSocket作爲單元測試的拆卸方法的一部分被關閉。由於我的代碼等待客戶端讀取服務器消息的時間長達五秒鐘,所以我認爲拆卸並不會造成干擾。在測試過程中,我還關閉了ServerSocket以模擬連接故障,請參閱我添加到我的描述中的段落以瞭解詳細信息 – user623257 2011-03-16 15:28:13

+0

關閉「ServerSocket」對從接受的套接字傳輸的數據沒有影響。如果你的意思是'Socket',在發送數據之前關閉它會導致send發送'socket is closed'異常。 – EJP 2014-08-04 00:18:49

0

任何人都可以確認(或反駁)我懷疑我必須保證客戶端在服務器調用寫入之前調用readline。

你不知道。服務器可以隨時發送它喜歡的內容。

,如果這是需要

它不是。

你的問題在別處。

0

我有同樣的問題,甚至想到一個繁瑣的確認過程。但事實上,您不需要等待read才能被調用,而且問題位於其他位置。

在我的情況下,我將閱讀調用委託給一個單獨的線程。但是JUnit測試成功完成雖然read在線程

  • 沒有被調用呢,
  • 仍然在閱讀過程中或
  • 更糟:線程甚至沒有達到運行狀態

當主jUnit線程已經終止。

爲了證明我的假設,你可以把等待放在單元測試的末尾,而不是「在套接字連接和服務器寫入調用之間」,並且發送/接收仍將工作。

只是爲了完整性:不要忘了叫flush()