java中Socket設置超時時間的兩種方式

Socket設置超時時間的兩種方式

方法1

調用Socket的connct 方法打開連接,並設置連接超時時間

Socket socket = new Socket()
socket.connect(new InetSocketAddress(ip, port), 3000); //設置超時3000毫秒

以上代碼是設置Socket的連接超時時間,當連接超時時,會拋出如下異常:

在不設置連接超時時間的情況下,socket默認的超時時間應該是20毫秒左右(我試瞭5次大概都是20毫秒就會拋出異常)

方法2

調用Socket的setSoTimeout 方法設置io讀取/寫出超時時間

socket.setSoTimeout(5000);  //設置超時時間5000毫秒
OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream();

當socket創建的IO流讀取或寫出超過瞭設定時間時,就會拋出異常

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)

如果不設置setSoTimeout的話,默認的io流讀寫超時時間大概是120秒(真是相當久啊)

整理一下二者的區別

雖然兩種超時拋出的異常都是SocketTimeoutException ,但是第一種連接超時,出現這種異常一般是ip或者端口填錯瞭。而第二種情況能出現的話,說明連接肯定建立成功瞭,可能是通訊的另一端響應的過慢,導致等待數據傳達的過程中超時瞭。

用一個現實生活中的例子的話。第一種情況就是打電話過去沒人接,等瞭10秒都沒人接我就掛瞭。第二種情況就是電話打通瞭,我等瞭你10秒你不給我說話,那我就掛瞭

設置socket超時時間的那些坑

通常情況下 這樣設置socket超時時間

方式1

final Socket socket = new Socket("ip","port");//自動開始連接ip
 
socket.setSoTimeout(Constants.userRequestOutTime);//設置超時時間
OutputStream outStream = socket.getOutputStream();

方式2

        final Socket socket = new Socket();
        InetSocketAddress socketAddress = new InetSocketAddress(Constants.ip,
                Integer.parseInt(Constants.port));
  
        //設置 超時時間
        socket.setSoTimeout(Constants.userRequestOutTime);
        socket.connect(socketAddress);//開始連接ip
       //
      OutputStream outStream = null;
      InputStream inStream = null;

但是 發現 在服務端沒有開啟的情況下 超時時間實際是30s,不是所設置的,結果研究發現

socket.setSoTimeout設置的是讀取/輸入io流數據時的超時時間
//--
socket.connect(socketAddress, Constants.userRequestOutTime);

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。

推薦閱讀: