您好,登錄后才能下訂單哦!
如何在Java中設置Socket超時時間?針對這個問題,今天小編總結了這篇文章,希望能幫助更多想解決這個問題的朋友找到更加簡單易行的辦法。
方式1:
Socket s=new Socket(); s.connect(new InetSocketAddress(host,port),10000);
方式2:
Socket s=new Socket("127.0.0.1",8080); s.setSoTimeout(10000);
那么這兩種方式設置的超時時間各自代表了什么意義呢?有什么區別呢?
第1種方式
我們先來看一下第1種方式,我們來測試一下:
在 main 方法中我們創建 Socket 連接到
ip :29.212.19.201,端口:2132
public static void main(String[] args) { Socket socket = new Socket(); SocketAddress endpoint = new InetSocketAddress("29.212.19.201", 2132); long timeMillis = System.currentTimeMillis(); try { socket.connect(endpoint, 10000); } catch (IOException e) { e.printStackTrace(); } System.out.println(System.currentTimeMillis()-timeMillis); System.out.println("end"); }
運行這段代碼,控制臺10秒之前沒有任何信息輸出,10秒后打印如下信息:
10002 java.net.SocketTimeoutException: connect timed out at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:589) at com.wakling.cn.SocketSever.main(SocketSever.java:33) end
可以看出,我們嘗試連接到29.212.19.201:2132時,連接了10秒都沒有連接上,于是就報了 java.net.SocketTimeoutException: connect timed out 的異常。
解釋一下,上述的 IP 是一個未知的 IP ,即我的 IP 在當前網絡環境中訪問不到這個 IP ,這樣我們的這個 Socket 才會去一直嘗試連接到此 IP 直到超時。如果 IP 是一個已知的 IP ,例如本地 127.0.0.1 加上一個未知的端口,那么此 Socket 連接會立馬報錯。
另外,在不設置連接超時時間的情況下,Socket 默認大概是21s(測試了3次都是21020毫秒)連接超時。如下是不設置連接超時時間的代碼:
Socket socket = new Socket("29.212.19.201", 2132);
第2種方式
然后我們來看一下第2種方式,這時候我們需要在我們本地寫一套 Socket 服務以及客戶端來模擬這個場景。
我們讓客戶端設置 setSoTimeout 為10s,在服務端代碼拿到客戶端請求信息后,休眠10s后再處理客戶端請求,返回響應。
我們來看一下效果,關鍵代碼如下:
//服務端 System.out.println("進入休眠,10s后醒來"); Thread.sleep(10000); System.out.println("休眠結束"); //返回響應 OutputStream outputStream = socket.getOutputStream();// 獲取一個輸出流,向服務端發送信息 PrintWriter printWriter = new PrintWriter(outputStream);// 將輸出流包裝成打印流 printWriter.print("你好,服務端已接收到您的信息"); printWriter.flush(); //客戶端 Socket socket = new Socket("127.0.0.1",2132); socket.setSoTimeout(10000);//read的超時時間
運行后,等待客戶端輸出,10s后客戶端控制臺輸出信息如下:
java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) at java.net.SocketInputStream.read(SocketInputStream.java:171) at java.net.SocketInputStream.read(SocketInputStream.java:141) at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) at java.io.InputStreamReader.read(InputStreamReader.java:184) at java.io.BufferedReader.fill(BufferedReader.java:161) at java.io.BufferedReader.readLine(BufferedReader.java:324) at java.io.BufferedReader.readLine(BufferedReader.java:389) at com.wakling.cn.SocketClient.main(SocketClient.java:36) 10020 end
這里10s后客戶端報錯 java.net.SocketTimeoutException: Read timed out 查看客戶端控制臺信息正常輸出,即使客戶端已報超時,服務端仍然繼續往下走,只是客戶端已經收不到服務端10s后發給自己的消息。
另外經測試發現,服務端休眠很久很久,如500s,在客戶端不設置 setSoTimeout 時,默認120s超時。
區別和意義
下面我們就來說一說二者的意義和區別。
方式1是客戶端與服務端進行連接的超時時間,即10秒內建立不了連接就報java.net.SocketTimeoutException: connect timed out 連接超時的異常。此時二者未建立連接,更別說服務端收到客戶端的消息了。
方式2是設置 inputStream.read() 方法的阻塞時間,即客戶端發出請求后等待服務端返回響應的等待時長,超過這個時長將會引發 java.net.SocketTimeoutException: Read timed out 異常。此時二者正常建立連接,服務端接收到了客戶端的請求。
兩種方式控制超時的側重點不同,就像打電話一樣,方法1是打電話10秒你不接電話我就掛了,方法2是打電話接通后,等你10秒不說話就掛,10秒后說不說話都不聽了。
關于在Java中設置Socket超時時間的方法就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。