jjzjj

ios - iPhone 上的网络事件监控

coder 2023-07-26 原文

我已经工作了 5 天,试图在 iPhone 上学习和实现网络监视器。 我查看了 apple 的 netstat 代码,我掉了大约 25% 的头发。

我找到了 JB 设备的链接,但我需要它在非 JB 设备上执行。 (无论 Apple 是否在 App store 上接受它)。

我找到了一些有用的链接:

how to get tcp udp opening port list on iPhone (我无法解析此问题中返回的数据 :( )

Data Usage on iPhone

sysctlbyname buf return type (我不是网络专家..无法理解这一点,也许你们可以提供帮助:))

TCP/UPD port list

我可以说我从第一个链接中得到了一些东西。你们能帮我解析数据吗? 还有其他方法可以实现吗??

最佳答案

好的,你已经准备好了所有你需要的东西。

可以查看问题Is there any private api to monitor network traffic on iPhone? 在这里你可以找到来源 code of inet .该代码具有解析 how to get tcp udp opening port list on iPhone 返回的数据所需的一切。

size_t len = 0;
if (sysctlbyname("net.inet.tcp.pcblist_n", 0, &len, 0, 0) < 0) {
    perror("sysctlbyname");
} else {
    char *buf = malloc(len);
    sysctlbyname("net.inet.tcp.pcblist_n", buf, &len, 0, 0);
    NSData *data = [NSData dataWithBytesNoCopy:buf length:len];
    NSLog(@"data = %@", data);
}

好的,是的,inet 的源代码有点复杂。但是,您知道 netstat 会打印网络状态。所以,你只需要看inet什么时候执行printf,此时你就已经解析出数据了。

如果你尝试为 iOS 编译 inet 的源码,你会发现很多问题:一些头文件在 ios sdk 中不存在。好的,没问题复制标题。

对于模拟器你只需要复制netstat.h的标题.并添加一些私有(private)的结构声明:

struct  xtcpcb_n {
    u_int32_t                      xt_len;
    u_int32_t                        xt_kind;                /* XSO_TCPCB */

    u_int64_t t_segq;
    int     t_dupacks;              /* consecutive dup acks recd */

    int t_timer[TCPT_NTIMERS_EXT];  /* tcp timers */

    int     t_state;                /* state of this connection */
    u_int   t_flags;

    int     t_force;                /* 1 if forcing out a byte */

    tcp_seq snd_una;                /* send unacknowledged */
    tcp_seq snd_max;                /* highest sequence number sent;
                                     * used to recognize retransmits
                                     */
    tcp_seq snd_nxt;                /* send next */
    tcp_seq snd_up;                 /* send urgent pointer */

    tcp_seq snd_wl1;                /* window update seg seq number */
    tcp_seq snd_wl2;                /* window update seg ack number */
    tcp_seq iss;                    /* initial send sequence number */
    tcp_seq irs;                    /* initial receive sequence number */

    tcp_seq rcv_nxt;                /* receive next */
    tcp_seq rcv_adv;                /* advertised window */
    u_int32_t rcv_wnd;              /* receive window */
    tcp_seq rcv_up;                 /* receive urgent pointer */

    u_int32_t snd_wnd;              /* send window */
    u_int32_t snd_cwnd;             /* congestion-controlled window */
    u_int32_t snd_ssthresh;         /* snd_cwnd size threshold for
                                     * for slow start exponential to
                                     * linear switch
                                     */
    u_int   t_maxopd;               /* mss plus options */

    u_int32_t t_rcvtime;            /* time at which a packet was received */
    u_int32_t t_starttime;          /* time connection was established */
    int     t_rtttime;              /* round trip time */
    tcp_seq t_rtseq;                /* sequence number being timed */

    int     t_rxtcur;               /* current retransmit value (ticks) */
    u_int   t_maxseg;               /* maximum segment size */
    int     t_srtt;                 /* smoothed round-trip time */
    int     t_rttvar;               /* variance in round-trip time */

    int     t_rxtshift;             /* log(2) of rexmt exp. backoff */
    u_int   t_rttmin;               /* minimum rtt allowed */
    u_int32_t t_rttupdated;         /* number of times rtt sampled */
    u_int32_t max_sndwnd;           /* largest window peer has offered */

    int     t_softerror;            /* possible error not yet reported */
    /* out-of-band data */
    char    t_oobflags;             /* have some */
    char    t_iobc;                 /* input character */
    /* RFC 1323 variables */
    u_char  snd_scale;              /* window scaling for send window */
    u_char  rcv_scale;              /* window scaling for recv window */
    u_char  request_r_scale;        /* pending window scaling */
    u_char  requested_s_scale;
    u_int32_t ts_recent;            /* timestamp echo data */

    u_int32_t ts_recent_age;        /* when last updated */
    tcp_seq last_ack_sent;
    /* RFC 1644 variables */
    tcp_cc  cc_send;                /* send connection count */
    tcp_cc  cc_recv;                /* receive connection count */
    tcp_seq snd_recover;            /* for use in fast recovery */
    /* experimental */
    u_int32_t snd_cwnd_prev;        /* cwnd prior to retransmit */
    u_int32_t snd_ssthresh_prev;    /* ssthresh prior to retransmit */
    u_int32_t t_badrxtwin;          /* window for retransmit recovery */
};


struct  xinpcb_n {
    u_int32_t               xi_len;         /* length of this structure */
    u_int32_t               xi_kind;                /* XSO_INPCB */
    u_int64_t               xi_inpp;
    u_short                 inp_fport;      /* foreign port */
    u_short                 inp_lport;      /* local port */
    u_int64_t               inp_ppcb;       /* pointer to per-protocol pcb */
    inp_gen_t               inp_gencnt;     /* generation count of this instance */
    int                             inp_flags;      /* generic IP/datagram flags */
    u_int32_t               inp_flow;
    u_char                  inp_vflag;
    u_char                  inp_ip_ttl;     /* time to live */
    u_char                  inp_ip_p;       /* protocol */
    union {                                 /* foreign host table entry */
        struct  in_addr_4in6    inp46_foreign;
        struct  in6_addr        inp6_foreign;
    }                               inp_dependfaddr;
    union {                                 /* local host table entry */
        struct  in_addr_4in6    inp46_local;
        struct  in6_addr        inp6_local;
    }                               inp_dependladdr;
    struct {
        u_char          inp4_ip_tos;    /* type of service */
    }                               inp_depend4;
    struct {
        u_int8_t        inp6_hlim;
        int                     inp6_cksum;
        u_short         inp6_ifindex;
        short           inp6_hops;
    }                               inp_depend6;
    u_int32_t               inp_flowhash;
};


#define SO_TC_STATS_MAX 4

struct data_stats {
    u_int64_t       rxpackets;
    u_int64_t       rxbytes;
    u_int64_t       txpackets;
    u_int64_t       txbytes;
};

struct xgen_n {
    u_int32_t   xgn_len;            /* length of this structure */
    u_int32_t   xgn_kind;       /* number of PCBs at this time */
};

#define XSO_SOCKET  0x001
#define XSO_RCVBUF  0x002
#define XSO_SNDBUF  0x004
#define XSO_STATS   0x008
#define XSO_INPCB   0x010
#define XSO_TCPCB   0x020

struct  xsocket_n {
    u_int32_t       xso_len;        /* length of this structure */
    u_int32_t       xso_kind;       /* XSO_SOCKET */
    u_int64_t       xso_so; /* makes a convenient handle */
    short           so_type;
    u_int32_t       so_options;
    short           so_linger;
    short           so_state;
    u_int64_t       so_pcb;     /* another convenient handle */
    int             xso_protocol;
    int             xso_family;
    short           so_qlen;
    short           so_incqlen;
    short           so_qlimit;
    short           so_timeo;
    u_short         so_error;
    pid_t           so_pgid;
    u_int32_t       so_oobmark;
    uid_t           so_uid;     /* XXX */
};

struct xsockbuf_n {
    u_int32_t       xsb_len;        /* length of this structure */
    u_int32_t       xsb_kind;       /* XSO_RCVBUF or XSO_SNDBUF */
    u_int32_t       sb_cc;
    u_int32_t       sb_hiwat;
    u_int32_t       sb_mbcnt;
    u_int32_t       sb_mbmax;
    int32_t         sb_lowat;
    short           sb_flags;
    short           sb_timeo;
};

struct xsockstat_n {
    u_int32_t       xst_len;        /* length of this structure */
    u_int32_t       xst_kind;       /* XSO_STATS */
    struct data_stats   xst_tc_stats[SO_TC_STATS_MAX];
};

但是对于 Device 你需要复制内核的一些其他头文件,我不知道为什么这些头文件不在设备 sdk 中(也许如果你使用它们苹果不会批准你的应用程序,我不知道知道,但这没关系)。

您可以将缺少的 header 从模拟器 SDK 复制到您的项目中。或者您可以将 header 路径更改为模拟器 SDK。 (我复制了标题)。
如果您复制 header ,则需要更改一些包含声明。

您不需要所有 inet.c 代码。您只需要这些功能:

  • 原型(prototype)
  • 网络打印
  • 网络名

然后在这些函数中,您将看到带有解析数据的 printf,您可以将其添加到字典中。

Here是我的代码。您可以看到一个名为:DHInet 的类,它有两个方法返回一个 NSArray,其中包含一个包含连接信息的 NSDictionary 列表。

我希望你觉得它有用,如果有人想帮助我改进代码,那就这样吧,我需要清理代码,因为它有很多不必要的 ifdef。

关于ios - iPhone 上的网络事件监控,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19977759/

有关ios - iPhone 上的网络事件监控的更多相关文章

  1. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  2. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  3. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  4. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  5. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  6. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  7. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

  8. Observability:从零开始创建 Java 微服务并监控它 (二) - 2

    这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/

  9. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  10. 网络编程套接字 - 2

    网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识

随机推荐