2015-04-27 38 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普遍问题。首先解决这个问题可能会解决这个问题。 –