引言:最近在做網(wǎng)絡訪問功能赴叹,用到了失敗重傳弓千,效果卻不理想齿诞。其問題點在于酸休,對同一個地址連續(xù)訪問多次,如果第一次失敗花了幾秒鐘的時間祷杈,后續(xù)訪問失敗根本不用花幾秒(甚至到了幾毫秒)就結(jié)束斑司。一度讓我懷疑,我應不應該做失敗重傳吠式,好在經(jīng)過我的實驗陡厘,找到了問題所在抽米,并得出了相應結(jié)論以及解決辦法。但更為深層次的原因糙置,還需要繼續(xù)探究云茸。所以現(xiàn)在跟我一起看看是怎么回事兒吧!
既然是失敗重傳谤饭,那么就得創(chuàng)造網(wǎng)絡訪問失敗的環(huán)境标捺,這個環(huán)境是這樣:手機正常連接路由器WiFi,將路由器WAN口的網(wǎng)線拔掉揉抵,即讓路由斷網(wǎng)亡容。
環(huán)境準備好了,就開始上代碼運行冤今,代碼詳情如下
println("lr------ programming launch")
for (i in 0 until 5) {
val start = System.currentTimeMillis()
var connection: HttpURLConnection? = null
try {
connection = URL("https://www.baidu.com").openConnection() as HttpURLConnection
connection.connectTimeout = 2000
connection.readTimeout = 2000
connection.connect()
} catch (e: Exception) {
println("lr------ err:$e")
} finally {
connection?.disconnect()
}
println("lr------ running time: " + (System.currentTimeMillis() - start) / 1_000.0 + "s")
}
println("lr------ programming end")
上述代碼進行了5次同一個地址的網(wǎng)絡連接請求闺兢,我們看看在我們創(chuàng)造網(wǎng)絡訪問失敗的環(huán)境的情況下的打印輸出
lr------ programming launch
lr------ err:java.net.UnknownHostException: Unable to resolve host "www.baidu.com": No address associated with hostname
lr------ running time: 16.043s
lr------ err:java.net.UnknownHostException: Unable to resolve host "www.baidu.com": No address associated with hostname
lr------ running time: 0.005s
lr------ err:java.net.UnknownHostException: Unable to resolve host "www.baidu.com": No address associated with hostname
lr------ running time: 0.005s
lr------ err:java.net.UnknownHostException: Unable to resolve host "www.baidu.com": No address associated with hostname
lr------ running time: 0.004s
lr------ err:java.net.UnknownHostException: Unable to resolve host "www.baidu.com": No address associated with hostname
lr------ running time: 0.004s
lr------ programming end
可以看到戏罢,第一網(wǎng)絡連接請求花了16s的時間屋谭,后續(xù)4次都只是花了幾毫秒,反復測試也是如此龟糕。后幾次的訪問看上去就是簡單復制了前一次的錯誤信息桐磁,根本沒有去真實的訪問網(wǎng)絡,或者說讲岁,第一次的連接或許沒有斷開過我擂,即便調(diào)用了connection?.disconnect()
如何解決這個問題呢,有了上面的猜想缓艳,我決定在每次網(wǎng)絡訪連接請求后都延時1200毫秒校摩,于是得到如下代碼
println("lr------ programming launch")
for (i in 0 until 5) {
val start = System.currentTimeMillis()
var connection: HttpURLConnection? = null
try {
connection = URL("https://www.baidu.com").openConnection() as HttpURLConnection
connection.connectTimeout = 2000
connection.readTimeout = 2000
connection.connect()
} catch (e: Exception) {
println("lr------ err:$e")
} finally {
connection?.disconnect()
}
println("lr------ running time: " + (System.currentTimeMillis() - start) / 1_000.0 + "s")
TimeUnit.MILLISECONDS.sleep(1200)
}
println("lr------ programming end")
運行后,打印輸出如下
lr------ programming launch
lr------ err:java.net.UnknownHostException: Unable to resolve host "www.baidu.com": No address associated with hostname
lr------ running time: 16.037s
lr------ err:java.net.UnknownHostException: Unable to resolve host "www.baidu.com": No address associated with hostname
lr------ running time: 0.002s
lr------ err:java.net.UnknownHostException: Unable to resolve host "www.baidu.com": No address associated with hostname
lr------ running time: 16.029s
lr------ err:java.net.UnknownHostException: Unable to resolve host "www.baidu.com": No address associated with hostname
lr------ running time: 0.006s
lr------ err:java.net.UnknownHostException: Unable to resolve host "www.baidu.com": No address associated with hostname
lr------ running time: 16.029s
lr------ programming end
通過這次打印輸出郎任,我發(fā)現(xiàn)其規(guī)律秧耗,無論我嘗試多少次,花費時間是間隔的舶治,即前一次花了16秒分井,后一次就花幾毫秒∶姑停看上去情況有所改善尺锚,猜想是延時時間設置小了,于是我改成了2000毫秒惜浅,再次運行后瘫辩,打印輸出如下
lr------ programming launch
lr------ err:java.net.UnknownHostException: Unable to resolve host "www.baidu.com": No address associated with hostname
lr------ running time: 16.195s
lr------ err:java.net.UnknownHostException: Unable to resolve host "www.baidu.com": No address associated with hostname
lr------ running time: 16.029s
lr------ err:java.net.UnknownHostException: Unable to resolve host "www.baidu.com": No address associated with hostname
lr------ running time: 16.03s
lr------ err:java.net.UnknownHostException: Unable to resolve host "www.baidu.com": No address associated with hostname
lr------ running time: 16.033s
lr------ err:java.net.UnknownHostException: Unable to resolve host "www.baidu.com": No address associated with hostname
lr------ running time: 16.031s
lr------ programming end
可以看到,幾次網(wǎng)絡連接請求花費的時間都是16秒左右,看上去這個問題解決了伐厌。但前面提到承绸,網(wǎng)絡連接請求同一個網(wǎng)絡地址的時候,會出現(xiàn)這個問題挣轨,那連續(xù)網(wǎng)絡連接請求的是不同的網(wǎng)絡地址會是一個怎樣的情況军熏,我們執(zhí)行下面的代碼來看情況
lr------ programming launch
lr------ err:java.net.UnknownHostException: Unable to resolve host "www.baidu0.com": No address associated with hostname
lr------ running time: 16.044s
lr------ err:java.net.UnknownHostException: Unable to resolve host "www.baidu1.com": No address associated with hostname
lr------ running time: 16.032s
lr------ err:java.net.UnknownHostException: Unable to resolve host "www.baidu2.com": No address associated with hostname
lr------ running time: 16.029s
lr------ err:java.net.UnknownHostException: Unable to resolve host "www.baidu3.com": No address associated with hostname
lr------ running time: 16.031s
lr------ err:java.net.UnknownHostException: Unable to resolve host "www.baidu4.com": No address associated with hostname
lr------ running time: 16.031s
lr------ programming end
看上去問題也得到解決了,此外卷扮,像Unable to resolve host "xxx"
這類錯誤杀糯,整個網(wǎng)絡連接請求流程沒有完全建立枪狂,為什么這么說呢藕施,因為抓包是抓不到滴@椭场!鞭铆!