2015-04-27 37 views
2

有一些很好的庫,如this from Apache,但這對我的目的來說有點太複雜。我需要的只是獲得HTTP延遲的最佳估計值(無論傳輸速度如何,與服務器連接所需的時間)。測試HTTP延遲的短代碼?

我嘗試HTTP連接代碼this answer

private void doPing() { 
    //Remember time before connection 
    long millis = System.currentTimeMillis(); 
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"))) { 
     //We don't need any data 
     reader.close(); 
     //Times is the array where we store our results 
     times.add((int)(System.currentTimeMillis()-millis)); 
     //I see lot's of these in console, so it's probably working 
     System.out.println("Request done..."); 
    } 
    //If internet is dead, does it throw exception? 
    catch(Exception e) { 
     times.add(-1); 
    } 
    } 

的事情是,我不敢肯定我是什麼測量。通過價值循環給了我這個結果:

Testing connection to http://www.seznam.cz 
     Threads: 5 
     Loops per thread: 50 
Given up waiting for results. 
Average time to connection: 53.8 [ms] 
Failures: 0.0% 

Testing connection to http://www.seznam.cz 
     Threads: 5 
     Loops per thread: 100 
Average time to connection: 43.58 [ms] 
Failures: 0.0% 

Testing connection to http://www.seznam.cz 
     Threads: 5 
     Loops per thread: 400 
Average time to connection: 30.145 [ms] 
Failures: 0.0% 

Testing connection to http://www.stackoverflow.com 
     Threads: 5 
     Loops per thread: 30 
Given up waiting for results. 
Average time to connection: 4006.1111111111113 [ms] 
Failures: 0.0% 

Testing connection to http://www.stackoverflow.com 
     Threads: 5 
     Loops per thread: 80 
Given up waiting for results. 
Average time to connection: 2098.695652173913 [ms] 
Failures: 0.0% 

Testing connection to http://www.stackoverflow.com 
     Threads: 5 
     Loops per thread: 200 
Given up waiting for results. 
Average time to connection: 0.0 [ms] 
//Whoops, connection dropped again 
Failures: 100.0% 

//Some random invalid url 
Testing connection to http://www.sdsfdser.tk/ 
     Threads: 4 
     Loops per thread: 20 
Average time to connection: 0.0 [ms] 
Failures: 100.0% 

不僅如此,我不敢肯定,如果我計算出我想要的東西(雖然它反映了我的經驗),我也不能肯定在非標準情況下什麼happes。

  • URL處理超時嗎?
  • 它會在超時時拋出異常嗎?

請記住,這個項目應該是簡單和輕量級的,你能告訴我,如果我做對了嗎?

+0

爲什麼線程?它不必要地使事情複雜化IMO – Diego

+0

因爲了解網絡如何處理併發連接很重要。然而,這與我是否使用線程無關。 –

+0

爲什麼不發送ping commnad:http://stackoverflow.com/questions/8815012/how-to-run-ping-command-and-get-ping-host-summary – Szarpul

回答

1

我認爲海林建議您創建一個原始Socket並將其連接到服務器,而不是使用URLConnection。我嘗試了兩種方法,並且您的版本的延遲更高。我認爲打開URLConnection必須在後臺做一些額外的東西,但我不知道是什麼。

不管怎麼說,這是一個使用Socket(根據需要添加異常處理)版本:

Socket s = new Socket(); 
SocketAddress a = new InetSocketAddress("www.google.com", 80); 
int timeoutMillis = 2000; 
long start = System.currentTimeMillis(); 
try { 
    s.connect(a, timeoutMillis); 
} catch (SocketTimeoutException e) { 
    // timeout 
} catch (IOException e) { 
    // some other exception 
} 
long stop = System.currentTimeMillis(); 
times.add(stop - start); 
try { 
    s.close(); 
} catch (IOException e) { 
    // closing failed 
} 

這將主機名解析(www.google.com中的例子),建立在一個80端口的TCP連接,並將毫秒數加到times如果您不想在那裏獲得DNS解析的時間,則可以在啓動計時器並將其傳遞給InetSocketAddress構造函數之前,使用InetAddress.getByName("hostname")創建InetAddress

編輯:InetSocketAddress的構造函數也立即解析主機名,所以從解析的IP地址構造它應該沒有區別。

+0

謝謝,這是有道理的。但是你確定即使我們什麼都不發送,測量的時間真的證實我們確實連接了嗎?我一直認爲,不知道套接字是否斷開,除非有一些心跳被執行...... –

+1

是的,我只是看看wireshark。我把它放在代碼中完成[TCP握手](https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Connection_establishment)。這是一個RTT,加上一點點的簿記開銷。一旦你發送最後的ACK,你可以認爲自己已經連接。順便說一下,wireshark在發送SYN和發送ACK之間測量了35毫秒,而程序輸出40,所以這裏有一些開銷(或者定時器不夠精確?)。 – dddsnn

+0

經過一番測試後,重要問題出現了。如果互聯網關閉(或非常慢),DNS解析最多可能需要5秒。與套接字連接方法不同,這不能設置超時或「中斷」。挖掘std庫資源後,我認爲這是一個Java普遍問題。首先解決這個問題可能會解決這個問題。 –