我编写了一个小小的android应用程序,发送http请求,从服务器接收响应,并计算发送和接收的字节数。
代码如下
long receivedBytes = TrafficStats.getUidRxBytes(uid)-lastNumer
我发现receivedbytes总是比http header+http body大,例如
我在服务器中捕捉到的实际http帧大小(使用wireshark)是1645字节(header+body),但是android api返回的receivedbytes是1912,所以传输是这样的。
trafficstats getuidrxbytes本身是不准确的(可能这个问题是我的平台三星i9300和cynogenmod 10.3特有的)
最后,我找到了正确的方法来计算数据使用量,我找到了其他方法来计算数据使用量,这似乎比trafficstats api更准确。
private long[] getStat() {
String line, line2;
long[] stats = new long[2];
try {
File fileSnd = new File("/proc/uid_stat/"+uid+"/tcp_snd");
File fileRcv = new File ("/proc/uid_stat/"+uid+"/tcp_rcv");
BufferedReader br1 = new BufferedReader(new FileReader(fileSnd));
BufferedReader br2 = new BufferedReader(new FileReader(fileRcv));
while ((line = br1.readLine()) != null&& (line2 = br2.readLine()) != null) {
stats[0] = Long.parseLong(line);
stats[1] = Long.parseLong(line2);
}
br1.close();
br2.close();
} catch (Exception e) {
e.printStackTrace();
}
return stats;
}
最佳答案
我知道你已经找到了一个解决方案,但是我会补充我对你的问题的想法,因为它可能对其他人有用(在搜索了如何使用trafficstats api之后,我自己也来到了这里)。
API documentation表示:
统计数据是在网络层测量的,因此包括TCP和UDP使用情况。
文档确实可能更详细,但我倾向于说,可以假设返回的字节计数还包括构成传输层头和网络层头的字节。
HTTP is an application layer protocol当计算预期的字节是http头字节加上http正文字节时,只处理应用程序层字节,因此不考虑传输和网络层头字节。我假设下载使用的是tcp。This adds a header ranging from 20 to 60 bytes此外,假设您正在使用ipv4进行下载。This also adds a header ranging from 20 to 60 bytes
显然,这不会占到整个1912-1645=267字节,但它可能会给您/其他人一些线索。
有点离题,但还是相关的。目前还不清楚trafficstats api是否真的计算了头字节。根据this answer,api不计算头字节。然而,考虑到上面列出的api文档,链接的答案可能规定了一些不正确的内容(至少不适用于api级别21)。此外,this question还提示trafficstats实际计算网络和传输层头字节(检查注释)。
trafficstats实际上计算网络和传输层的头字节数。请参见kernel source和TrafficStatsTest。