有一些很好的库,比如this from Apache,但这对我来说有点太复杂了。我需要的是获得HTTP延迟的最佳估计(与服务器连接所需的时间,无论传输速度如何)。
我尝试了来自this answer的HTTP连接代码:
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%
不仅如此,我不确定我是否计算了我想要的东西(尽管它反映了我的经验),我也不确定在非标准情况下会发生什么。
虽然请记住这个项目应该简单轻便,你能否告诉我,我做得对吗?
答案 0 :(得分:1)
我认为hailin建议您创建一个原始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解析,可以在启动计时器之前使用InetAddress
创建InetAddress.getByName("hostname")
并将其传递给InetSocketAddress
构造函数。 德尔>
编辑:InetSocketAddress
的构造函数也会立即解析主机名,因此从已解析的IP地址构建它不应该有所作为。