我写了一个小的Android应用程序,发送Http请求,从服务器接收响应,并计算发送和接收的字节数。 代码简单如下
long receivedBytes = TrafficStats.getUidRxBytes(uid)-lastNumer
我发现receiveBytes总是大于http Header + http Body的大小 我在服务器中捕获的实际http帧的大小(使用wireshark)是1645字节(标题+正文),但android API返回的receiveBytes是1912,所以作为传输。
TrafficStats getUidRxBytes本身不准确(可能是这个问题特定于我的平台samsung i9300与cynogenmod 10.3)
最后,我找到了计算数据使用情况的正确方法,我找到了其他方法来计算数据使用情况,这似乎比TrafficStats API更准确。(非常感谢here)
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;
}
答案 0 :(得分:4)
我发现您已经找到了解决方案,但我会在您的问题上添加我的想法,因为它可能对其他人有用(在谷歌搜索如何使用TrafficStats API后自己结束)
统计信息是在网络层测量的,因此它们包括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实际上是否计算头字节数,则不太清楚。根据{{3}},API执行不计数标头字节。但是,考虑到上面列出的API文档,链接的答案可能会规定一些不正确的事情(至少不适用于API级别21)。此外,this answer还暗示TrafficStats实际上计算网络和传输层头字节(检查注释)。
TrafficStats实际上计算网络和传输层标头字节。请参阅this question和kernel source。
答案 1 :(得分:0)
根据我的理解,你应该将getUidRxBytes与getUidRxPackets结合起来。
你应该有类似的东西:getUidRxBytes = getUidRxPackets *(tcp / ip header size)