本文介绍了如何使用 Xamarin/monotouch 从互联网收集数据使用信息到 iPhone的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要从 iphone 上的互联网数据使用中收集信息,我使用的以下 C# 代码仅返回 0 个值.

I'm needing to collect information from internet data usage on the iphone, the below code in C # I'm using only returns 0 values​​.

我使用的是正确的课程吗?

I'm using the right class?

有一些我需要在 Xamarin 中添加的参考吗?

have some reference I need to add in Xamarin?

出现在mono 3类类中,巧合的是MacOsIPv4InterfaceStatistics"接口总是返回固定值0.

appears in mono 3 types of classes, Coincidentally the "MacOsIPv4InterfaceStatistics" interface always returns the fixed value 0.

https://github.com/mono/mono/blob/master/mcs/class/System/System.Net.NetworkInformation/IPv4InterfaceStatistics.cs

Win32IPv4InterfaceStatistics
LinuxIPv4InterfaceStatistics
MacOsIPv4InterfaceStatistics


using System;
using System.Net;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using System.Threading;
using MonoTouch.ObjCRuntime;


namespace Taximetro { public delegate void Update();

public static class ControleUso
{
    public static long controller;

    public static long BytesReceivedWiFi;
    public static long BytesSentWiFi;

    public static long BytesReceived3G;
    public static long BytesSent3G;

    public static Update UpdateMethod;

    public static void DoWork()
    {    
        foreach (var netint in NetworkInterface.GetAllNetworkInterfaces()) {
            var stats = netint.GetIPv4Statistics ();

            //WiFi
            //if (netint.Name.StartsWith ("en")) {
                BytesReceivedWiFi += stats.BytesReceived;
                BytesSentWiFi += stats.BytesSent;
            //}

            //3G
            if (netint.Name.StartsWith ("pdp_ip")) {
                BytesReceived3G += stats.BytesReceived;
                BytesSent3G += stats.BytesSent;
            }
        }
        controller++;
        if (UpdateMethod != null) {
            UpdateMethod ();
        }
        Thread.Sleep (1000);
    }
}

}

推荐答案

注意 data 是 uint 并且不是 long,这意味着每 4GB 数据就会溢出.

Notice that data is uint and not long, which means it will overflow every 4GB of data.

经过一番谷歌搜索后,我注意到这些数据在 iOS 重启时被重置.只是给可能会使用它的任何人一些提醒.

After some Googling around I noticed that this data is reset on iOS reboot. Just some heads ups to anyone who might use this.

public enum InterfaceTypes
{
    Wifi,
    Cellular
}

public class DataUsage
{
    [DllImport ("libc")]
    static extern int getifaddrs (out IntPtr ifap);

    [DllImport ("libc")]
    static extern void freeifaddrs (IntPtr ifap);

    const int AF_LINK = 18;

    struct ifaddrs
    {
        public IntPtr ifa_next;
        public string ifa_name;
        public uint ifa_flags;
        public IntPtr ifa_addr;
        public IntPtr ifa_netmask;
        public IntPtr ifa_dstaddr;
        public IntPtr ifa_data;
    }

    public InterfaceTypes InterfaceType {
        get;
        private set;
    }

    public uint BytesSent {
        get;
        private set;
    }

    public uint BytesReceived {
        get;
        private set;
    }

    public static List<DataUsage> GetAllNetworkInterfacesUsage ()
    {
        IntPtr ifap;
        if (getifaddrs (out ifap) != 0)
            throw new SystemException ("getifaddrs() failed");

        List<DataUsage> usages = new List<DataUsage> ();
        try {
            IntPtr next = ifap;
            while (next != IntPtr.Zero) {
                ifaddrs addr = (ifaddrs)Marshal.PtrToStructure (next, typeof(ifaddrs));
                next = addr.ifa_next;
                string name = addr.ifa_name;
                if (addr.ifa_addr != IntPtr.Zero) {
                    if (Marshal.ReadByte (addr.ifa_addr, 1) == AF_LINK) {
                        if (!name.StartsWith ("en") && !name.StartsWith ("pdp_ip"))
                            continue;
                        usages.Add (new DataUsage () {
                            InterfaceType = name.StartsWith ("en") ? InterfaceTypes.Wifi : InterfaceTypes.Cellular,
                            BytesReceived = (uint)Marshal.ReadInt32 (addr.ifa_data, 40),
                            BytesSent = (uint)Marshal.ReadInt32 (addr.ifa_data, 44)
                        });
                    }
                }
            }

        } finally {
            freeifaddrs (ifap);
        }
        return usages;
    }
}

这篇关于如何使用 Xamarin/monotouch 从互联网收集数据使用信息到 iPhone的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-02 13:18