簡體   English   中英

如何強制 Java Socket 的 InputStream 拋出 IOException?

[英]How do I force a Java Socket's InputStream to throw an IOException?

我正在測試我在java.net.Socket之上構建的網絡組件。 我有這樣的代碼:

try {
   byte[] buffer = new byte[1024]
   int bytesRead = socket.getInputStream().read(buffer);
   // more processing
} catch (IOException e) {
   handleException(e);
}

如何強制InputStream#read調用拋出IOException以便測試handleException方法? 我不想使用 mocking。 我想使用真正的實現,我只想使用 Java API。

TLDR

從寫作方面來看,使用失敗的關閉:

socket.setSoLinger(true, 0);
socket.close();

這將導致來自另一端的任何后續讀取拋出IOException

來自 Oracle 文檔的更多詳細信息:

首先,我們需要區分中止連接釋放和有序連接釋放之間的區別。 為了理解這種區別,我們需要看看在 TCP 協議級別發生了什么。 將已建立的 TCP 連接想象為實際上是兩個獨立的半獨立數據流是有幫助的。 如果兩個peer分別是A和B,那么一個stream將數據從A傳遞到B,另一個stream從B傳遞到A。有序發布分兩個階段。 第一方(比如 A)決定停止發送數據並向 B 發送 FIN 消息。當 B 側的 TCP 堆棧收到 FIN 時,它知道不再有數據來自 A,並且每當 B 讀取所有先前的數據時套接字,進一步讀取將返回值 -1 以指示文件結束。 這個過程被稱為 TCP 半關閉,因為只有一半的連接是關閉的。 毫不奇怪,另一半的程序完全相同。 B 向 A 發送 FIN 消息,A 在從套接字讀取 A 之前發送的所有數據后最終收到 -1。

相比之下,異常關閉使用 RST(重置)消息。 如果任何一方發出 RST,這意味着整個連接被中止,並且 TCP 堆棧可以丟棄任何尚未由任一應用程序發送或接收的排隊數據。

那么,Java 應用程序如何執行有序且中止的發布? 讓我們首先考慮流產的版本。 自原始 BSD sockets 時代以來就存在的約定是,“linger”套接字選項可用於強制中止連接釋放。 任何一個應用程序都可以調用 Socket.setLinger (true, 0) 來告訴 TCP 堆棧,當此套接字關閉時,將使用中止 (RST) 過程。 設置 linger 選項不會立即產生影響,除了隨后調用 Socket.close() 時,連接會通過 RST 消息中止。 正如我們稍后將看到的,還有其他可能導致連接中止的方法,但這是實現它的最簡單方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM