1. 程式人生 > >HttpClient的幾個超時時間

HttpClient的幾個超時時間

TCP Socket

連線超時:

如果應用層不能及時接受已被TCP接受的連線,這些連線可能佔滿整個連線佇列,新的連線請求可能不被響應而會超時。如果一個連線請求SYN傳送後,一段時間後沒有收到確認SYN+ACK,TCP會重傳這個連線請求SYN兩次每次重傳的時間間隔加倍,在規定的時間內仍沒有收到SYN+ACK,TCP將放棄這個連線請求,連線建立就超時了。

  JAVA Socket連線建立超時和TCP是相同的,如果TCP建立連線時三次握手超時,那麼導致Socket連線建立也就超時了。

如果在timeout內,連線沒有建立成功,在TimeoutException異常被丟擲。如果timeout的值小於三次握手的時間,那麼Socket連線永遠也不會建立。



讀超時:

read超時設定有意義,在伺服器處理能力差,但最終會響應的情況下,可以將客戶端的等待響應時間設長一些。如果太長的話,由於客戶端使用的是BIO的方式,執行緒會一直阻塞在IO而導致掛起。當客戶端的處理能力明顯快於服務端,這樣掛起的執行緒會很多。

如果輸入緩衝佇列RecvQ中沒有資料,read操作會一直阻塞而掛起執行緒,直到有新的資料到來或者有異常產生。呼叫setSoTimeout(int timeout)可以設定超時時間,如果到了超時時間仍沒有資料,read會丟擲一個SocketTimeoutException,程式需要捕獲這個異常,但是當前的socket連線仍然是有效的。

  如果對方程序崩潰、對方機器突然重啟、網路斷開,本端的read會一直阻塞下去,這時設定超時時間是非常重要的,否則呼叫read的執行緒會一直掛起。

  TCP模組把接收到的資料放入RecvQ中,直到應用層呼叫輸入流的read方法來讀取。如果RecvQ佇列被填滿了,這時TCP會根據滑動視窗機制通知對方不要繼續傳送資料,本端停止接收從對端傳送來的資料,直到接收者應用程式呼叫輸入流的read方法後騰出了空間。


寫超時:

TCP有寫重傳的概念,一般8m內會重試,否則,直接斷開連線

  socket的寫超時是基於TCP的超時重傳。超時重傳是TCP保證資料可靠性傳輸的一個重要機制,其原理是在傳送一個數據報文後就開啟一個計時器,在一定時間內如果沒有得到傳送報文的確認ACK,那麼就重新發送報文。如果重新發送多次之後,仍沒有確認報文,就傳送一個復位報文RST,然後關閉TCP連線。首次資料報文傳送與復位報文傳輸之間的時間差大約為9分鐘,也就是說如果9分鐘內沒有得到確認報文,就關閉連線

。但是這個值是根據不同的TCP協議棧實現而不同。

  如果傳送端呼叫write持續地寫出資料,直到SendQ佇列被填滿。如果在SendQ佇列已滿時呼叫write方法,則write將被阻塞,直到SendQ有新的空閒空間為止,也就是說直到一些位元組傳輸到了接收者套接字的RecvQ中。如果此時RecvQ佇列也已經被填滿,所有操作都將停止,直到接收端呼叫read方法將一些位元組傳輸到應用程式。

 當Socket的write傳送資料時,如果網線斷開、對端程序崩潰或者對端機器重啟動,TCP模組會重傳資料,最後超時而關閉連線。下次如再呼叫write會導致一個異常而退出。

 Socket寫超時是基於TCP協議棧的超時重傳機制,一般不需要設定write的超時時間,也沒有提供這種方法。