好的,您已经拥有了桌子上所有需要的东西。
您可以查看问题“iPhone上是否有任何私有API可用于监视网络流量?”在这里您可以找到inet代码的源代码。该代码包含了解析返回的数据所需的全部内容,如何获取iPhone上的TCP UDP开放端口列表。
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的标头文件。并添加一些私有结构声明:
struct xtcpcb_n {
u_int32_t xt_len;
u_int32_t xt_kind;
u_int64_t t_segq;
int t_dupacks;
int t_timer[TCPT_NTIMERS_EXT];
int t_state;
u_int t_flags;
int t_force;
tcp_seq snd_una;
tcp_seq snd_max;
tcp_seq snd_nxt;
tcp_seq snd_up;
tcp_seq snd_wl1;
tcp_seq snd_wl2;
tcp_seq iss;
tcp_seq irs;
tcp_seq rcv_nxt;
tcp_seq rcv_adv;
u_int32_t rcv_wnd;
tcp_seq rcv_up;
u_int32_t snd_wnd;
u_int32_t snd_cwnd;
u_int32_t snd_ssthresh;
u_int t_maxopd;
u_int32_t t_rcvtime;
u_int32_t t_starttime;
int t_rtttime;
tcp_seq t_rtseq;
int t_rxtcur;
u_int t_maxseg;
int t_srtt;
int t_rttvar;
int t_rxtshift;
u_int t_rttmin;
u_int32_t t_rttupdated;
u_int32_t max_sndwnd;
int t_softerror;
char t_oobflags;
char t_iobc;
u_char snd_scale;
u_char rcv_scale;
u_char request_r_scale;
u_char requested_s_scale;
u_int32_t ts_recent;
u_int32_t ts_recent_age;
tcp_seq last_ack_sent;
tcp_cc cc_send;
tcp_cc cc_recv;
tcp_seq snd_recover;
u_int32_t snd_cwnd_prev;
u_int32_t snd_ssthresh_prev;
u_int32_t t_badrxtwin;
};
struct xinpcb_n {
u_int32_t xi_len;
u_int32_t xi_kind;
u_int64_t xi_inpp;
u_short inp_fport;
u_short inp_lport;
u_int64_t inp_ppcb;
inp_gen_t inp_gencnt;
int inp_flags;
u_int32_t inp_flow;
u_char inp_vflag;
u_char inp_ip_ttl;
u_char inp_ip_p;
union {
struct in_addr_4in6 inp46_foreign;
struct in6_addr inp6_foreign;
} inp_dependfaddr;
union {
struct in_addr_4in6 inp46_local;
struct in6_addr inp6_local;
} inp_dependladdr;
struct {
u_char inp4_ip_tos;
} 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;
u_int32_t xgn_kind;
};
#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;
u_int32_t xso_kind;
u_int64_t xso_so;
short so_type;
u_int32_t so_options;
short so_linger;
short so_state;
u_int64_t so_pcb;
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;
};
struct xsockbuf_n {
u_int32_t xsb_len;
u_int32_t xsb_kind;
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;
u_int32_t xst_kind;
struct data_stats xst_tc_stats[SO_TC_STATS_MAX];
};
但是对于设备,您需要复制一些内核的其他头文件,我不知道为什么这些头文件不在设备sdk中(也许如果您使用它们,苹果将不会批准您的应用程序,我不知道,但这不重要)。
您可以从模拟器SDK中复制缺失的头文件到项目中。或者您可以更改头文件路径以指向模拟器SDK。(我复制了这些头文件)。
如果您复制了这些头文件,则需要更改一些包含声明。
您不需要全部的inet.c代码。您只需要以下几个函数:
- protopr
- inetprint
- inetname
然后在这些函数中,您将看到解析数据的printf,您可以将其添加到字典中。
这里是我的代码。您可以看到一个名为DHInet的类,其中有两种方法,返回一个包含连接信息的NSDictionary列表的NSArray。
希望您觉得这很有用,如果有人想帮助我改进代码,那就太好了,我需要清理代码,因为它有很多不必要的ifdef。