最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java Socket設(shè)置timeout的幾種常用方式說明

 更新時間:2022年11月09日 14:19:24   作者:worldchinalee  
這篇文章主要介紹了Java Socket設(shè)置timeout的幾種常用方式說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

Java的網(wǎng)絡(luò)編程Socket常常用于各種網(wǎng)絡(luò)工具,比如數(shù)據(jù)庫的jdbc客戶端,redis客戶端jedis,各種RPC工具java客戶端,這其中存在一些參數(shù)來配置timeout,但是之前一直對timeout的理解還不清晰,所以會導致使用這些網(wǎng)絡(luò)工具的時候有點迷茫。在此做個總結(jié)。

1. Socket timeout

Java socket有如下兩種timeout:

  • 建立連接timeout,暫時就叫 connect timeout
  • 讀取數(shù)據(jù)timeout,暫時就叫so timeout 

1.1 建立連接connect timeout

當不設(shè)置該參數(shù)時,指客戶端請求和服務(wù)端建立tcp連接時,會一直阻塞直到連接建立成功,或拋異常。當設(shè)置了connectTimeout, 客戶端請求和服務(wù)端建立連接時,阻塞時間超過connectTimeout時,就會拋出異常java.net.ConnectException: Connection timed out: connect。

我們看如下精簡后的代碼,首先是服務(wù)端:

serverSocket = new ServerSocket(8080);?
Socket socket = serverSocket.accept();?

服務(wù)端開啟ServerSocket監(jiān)聽8080端口,再看客戶端:

socket = new Socket();?
socket.connect(new InetSocketAddress("localhost", 8080));?
System.out.println("Connected.");

打印“Connected.”,修改客戶端代碼中的主機名為一個不存在的主機:

socket = new Socket();?
long t1 = 0;?
try {?
t1 = System.currentTimeMillis();?
socket.connect(new InetSocketAddress("www.ss.ssss", 8080));?
} catch (IOException e) {?
long t2 = System.currentTimeMillis();?
e.printStackTrace();?
System.out.println("Connect failed, take time -> " + (t2 - t1) + "ms.");?
}

拋出異常:java.net.ConnectException: Connection timed out: connect,并打?。篊onnect failed, take time -> 18532ms. 也就是當未設(shè)置connect timeout時,connect方法會阻塞直到底層異常拋出。經(jīng)過測試socket有個默認的超時時間,大概在20秒左右(測試的值,不一定準確,待研究JVM源碼)。

下面我們來設(shè)置connect timeout,再看看效果:

socket = new Socket();?
long t1 = 0;?
try {?
t1 = System.currentTimeMillis();?
// 設(shè)置connect timeout 為2000毫秒?
socket.connect(new InetSocketAddress("www.ss.ssss", 8080), 2000);?
} catch (IOException e) {?
long t2 = System.currentTimeMillis();?
e.printStackTrace();?
System.out.println("Connect failed, take time -> " + (t2 - t1) + "ms.");?
}

拋出異常:java.net.SocketTimeoutException: connect timed out,并打?。篊onnect failed, take time -> 2014ms. 這里就是connect timeout發(fā)揮作用了。

1.2 讀取數(shù)據(jù)so timeout

先看下jdk源碼注釋:

Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds.  

With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time.  

If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. The option must be enabled prior to entering the blocking operation to have effect.

The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout.    

這個參數(shù)通過socket.setSoTimeout(int timeout)方法設(shè)置,可以看出它的意思是,socket關(guān)聯(lián)的InputStream的read()方法會阻塞,直到超過設(shè)置的so timeout,就會拋出SocketTimeoutException。

當不設(shè)置這個參數(shù)時,默認值為無窮大,即InputStream的read方法會一直阻塞下去,除非連接斷開。

下面通過代碼來看下效果:

服務(wù)端代碼:

serverSocket = new ServerSocket(8080);?
Socket socket = serverSocket.accept();?

服務(wù)端只接受socket但不發(fā)送任何數(shù)據(jù)給客戶端??蛻舳舜a:

socket = new Socket();?
socket.connect(new InetSocketAddress("localhost", 8080));?
System.out.println("Connected.");?
in = socket.getInputStream();?
System.out.println("reading...");?
in.read();?
System.out.println("read end");

客戶端建立連接就開始讀取InputStream。打印:

Connected.
reading...

并且一直阻塞在in.read(); 上。接下來我設(shè)置so timeout,代碼如下:

long t1 = 0;?
try {?
socket = new Socket();?
socket.connect(new InetSocketAddress("localhost", 8080));?
// 設(shè)置so timeout 為2000毫秒?
socket.setSoTimeout(2000);?
System.out.println("Connected.");?
in = socket.getInputStream();?
System.out.println("reading...");?
t1 = System.currentTimeMillis();?
in.read();?
} catch (IOException e) {?
long t2 = System.currentTimeMillis();?
System.out.println("read end, take -> " + (t2 - t1) + "ms");?
e.printStackTrace();?
} finally {?
if (this.reader != null) {?
try {?
this.reader.close();?
} catch (IOException e) {?
}?
}?
}

拋出異常:java.net.SocketTimeoutException: Read timed out, 打?。簉ead end, take -> 2000ms , 說明so timeout起作用了。

1.3 小結(jié)

我們可以通過設(shè)置connect timeout來控制連接建立的超時時間(不是絕對的,當設(shè)置的主機名不合法,比如我設(shè)置主機名為abc,會拋異常java.net.UnknownHostException: abc,但是此時connect timeout設(shè)置是不起作用的,測試得出的結(jié)論,僅供參考)。

通過設(shè)置so timeout可以控制流讀取數(shù)據(jù)的超時時間。

2. 使用案例

2.1 MySQL jdbc timeout

查閱MySQL Connector/J 5.1 Developer Guide 中的jdbc配置參數(shù),有

connectTimeout

Timeout for socket connect (in milliseconds), with 0 being no timeout. Only works on JDK-1.4 or newer. Defaults to '0'.

Default: 0

Since version: 3.0.1

socketTimeout

Timeout on network socket operations (0, the default means no timeout).

Default: 0

Since version: 3.0.1

這兩個參數(shù)分別就是對應(yīng)上面我們分析的connect timeout和so timeout。

參數(shù)的設(shè)置方法有兩種,一種是通過url設(shè)置,

jdbc:mysql://[host1][:port1][,[host2][:port2]]...[/[database]] [?propertyName1=propertyValue1[&propertyName2=propertyValue2]...]

即在url后面通過?加參數(shù),比如

jdbc:mysql://192.168.1.1:3306/test?connectTimeout=2000&socketTime=2000

還有一種方式是:

Properties info = new Properties();?
info.put("user", this.username);?
info.put("password", this.password);?
info.put("connectTimeout", "2000");?
info.put("socketTime", "2000");?
return DriverManager.getConnection(this.url, info);?

2.2 Jedis timeout

Jedis是最流行的redis java客戶端工具,redis.clients.jedis.Jedis對象的構(gòu)造器中就有參數(shù)設(shè)置,

public Jedis(final String host, final int port, final int connectionTimeout, final int soTimeout) {?
super(host, port, connectionTimeout, soTimeout);?
}?
// 用一個參數(shù)timeout同時設(shè)置connect timeout 和 so timeout?
public Jedis(final String host, final int port, final int timeout) {?
super(host, port, timeout);?
}

Jedis中so timeout個人覺得是有比較重要意義的,首先jedis so timeout默認值為2000毫秒,jedis的操作流程是客戶端發(fā)送命令給服務(wù)器端執(zhí)行,然后客戶端就開始執(zhí)行InputStream.read()讀取響應(yīng),當某個命令比較耗時(比如數(shù)據(jù)非常多的情況下執(zhí)行“keys *”),而導致客戶端遲遲沒有收到響應(yīng),就可能導致java.net.SocketTimeoutException: Read timed out異常拋出。

一般是不建議客戶端執(zhí)行非常耗時的命令,但是也不排除有這種特殊邏輯,那這時候就有可能需要修改Jeids中這個so timeout的值。

3. 總結(jié)

了解了這兩個timeout之后,可以更好的處理一些網(wǎng)絡(luò)服務(wù)的客戶端和服務(wù)端,同時對排查一些問題也很有幫助。

一般的成熟的網(wǎng)絡(luò)服務(wù)和客戶端都應(yīng)該有這兩個參數(shù)的配置方法,當使用遇到類似問題可以從這個方向去考慮下。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringMVC上傳和解析Excel方法

    SpringMVC上傳和解析Excel方法

    這篇文章主要介紹了SpringMVC上傳和解析Excel方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • Java輕松使用工具類實現(xiàn)獲取wav時間長度

    Java輕松使用工具類實現(xiàn)獲取wav時間長度

    在Java中,工具類定義了一組公共方法,這篇文章將介紹Java中使用工具類來獲取一個wav文件的時間長度,感興趣的同學繼續(xù)往下閱讀吧
    2021-10-10
  • Maven Plugins報錯的解決方法

    Maven Plugins報錯的解決方法

    本文主要介紹了Maven Plugins報錯的解決方法,文中通過圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-02-02
  • Java生成讀取條形碼和二維碼的簡單示例

    Java生成讀取條形碼和二維碼的簡單示例

    條形碼(barcode)是將寬度不等的多個黑條和空白,按照一定的規(guī)則排列,用來表示一組信息的圖形標識符,而二維碼大家應(yīng)該都很熟悉了,這篇文章主要給大家介紹了關(guān)于Java生成讀取條形碼和二維碼的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • Java 下數(shù)據(jù)業(yè)務(wù)邏輯開發(fā)技術(shù) JOOQ 和 SPL

    Java 下數(shù)據(jù)業(yè)務(wù)邏輯開發(fā)技術(shù) JOOQ 和 SPL

    這篇文章主要為大家介紹了Java 下數(shù)據(jù)業(yè)務(wù)邏輯開發(fā)技術(shù) JOOQ 和 SPL詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • idea導入module全流程

    idea導入module全流程

    這篇文章主要介紹了idea導入module全流程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • spring cloud中微服務(wù)之間的調(diào)用以及eureka的自我保護機制詳解

    spring cloud中微服務(wù)之間的調(diào)用以及eureka的自我保護機制詳解

    這篇文章主要介紹了spring cloud中微服務(wù)之間的調(diào)用以及eureka的自我保護機制詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • Java中字符串常見的一些拼接方式總結(jié)

    Java中字符串常見的一些拼接方式總結(jié)

    字符串拼接是我們在Java代碼中比較經(jīng)常要做的事情,就是把多個字符串拼接到一起,下面這篇文章主要給大家總結(jié)介紹了關(guān)于Java中字符串常見的一些拼接方式,需要的朋友可以參考下
    2023-04-04
  • Java雜談之代碼重構(gòu)的方法多長才算長

    Java雜談之代碼重構(gòu)的方法多長才算長

    關(guān)于代碼重構(gòu)的理解:在不改變軟件系統(tǒng)/模塊所具備的功能特性的前提下,遵循/利用某種規(guī)則,使其內(nèi)部結(jié)構(gòu)趨于完善。其在軟件生命周期中的價值體現(xiàn)主要在于可維護性和可擴展性
    2021-10-10
  • Java實現(xiàn)XML與JSON秒級轉(zhuǎn)換示例詳解

    Java實現(xiàn)XML與JSON秒級轉(zhuǎn)換示例詳解

    這篇文章主要為大家介紹了Java實現(xiàn)XML與JSON秒級轉(zhuǎn)換示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09

最新評論

南平市| 缙云县| 大港区| 张家界市| 蒲城县| 锦州市| 阿克陶县| 京山县| 遂溪县| 丽水市| 岢岚县| 临猗县| 西安市| 武胜县| 海安县| 古浪县| 东莞市| 辽宁省| 呼图壁县| 资中县| 白山市| 左权县| 从江县| 于都县| 辛集市| 孟津县| 山阴县| 苍山县| 久治县| 鹤壁市| 林周县| 庐江县| 舟曲县| 宜章县| 建湖县| 林甸县| 丹棱县| 青龙| 湘乡市| 高邑县| 交城县|