安卓TrafficStats getUidRxBytes不准确

4

我写了一个简单的安卓应用程序,向服务器发送Http请求,接收响应,并计算传输和接收的字节数。 代码如下:

long receivedBytes = TrafficStats.getUidRxBytes(uid)-lastNumer

我发现receivedBytes始终比http Header和http Body的大小大,例如,在服务器中使用wireshark捕获的实际http帧的大小为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;
}
2个回答

6
我看到你已经找到了解决方案,但是我会就你的问题发表一些看法,因为这可能对其他人有用(在谷歌搜索如何使用TrafficStats API后,我也来到了这里)。 API文档 表示:
网络层测量统计数据,因此包括TCP和UDP使用情况。
文档确实可以更详细,但我倾向于认为返回的字节数也包括传输层头部和网络层头部所占的字节。

HTTP是一个应用层协议。当你计算期望的字节数时,只涉及应用层字节,因此不考虑传输和网络层头字节。我假设下载使用TCP。这会添加20到60个字节的头部信息。此外,假设您正在使用IPv4进行下载。这也会添加20到60个字节的头部信息

显然,这不会涵盖整个1912-1645 = 267字节,但它可能会给您/其他人一些线索。


有点离题,但仍然相关。 TrafficStats API 是否实际计算头字节并不太清楚。根据 this answer ,API 计算头字节。然而,根据上面列出的 API 文档,链接的答案可能在说明某些不正确的事情(至少对于 API 级别 21 不是这样)。此外,this question 还暗示 TrafficStats 实际上计算网络和传输层头字节(请检查评论)。
TrafficStats实际上计算的是网络和传输层头字节数。请参见内核源代码TrafficStatsTest

0
根据我的理解,你应该将getUidRxBytes和getUidRxPackets结合起来使用。
你应该有类似以下的公式:getUidRxBytes = getUidRxPackets * (TCP/IP头大小)。

IP头大小不是在20-60字节之间变化吗? - Mateen Ulhaq

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接