只是一个简单的demo
可以优化的更好
(思路: 上行展示, 下行展示)
001 | // NetSpeed.cpp : Defines the entry point for the console application. |
002 | // |
003 |
004 | #include "stdafx.h" |
005 | #include <pcap.h> |
006 | #include <remote-ext.h> |
007 | #include <Winsock2.h> |
008 | #pragma comment(lib,"wpcap.lib") |
009 | #pragma comment(lib,"ws2_32.lib") |
010 |
011 | timeval timebegin={0}; |
012 | timeval timeend={0}; |
013 | int ktime = 0; |
014 | int Capturelen = 0; |
015 | /* packet handler 函数原型 */ |
016 | void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data); |
017 |
018 | main() |
019 | { |
020 | pcap_if_t *alldevs; |
021 | pcap_if_t *d; |
022 | int inum; |
023 | int i=0; |
024 | pcap_t *adhandle; |
025 | char errbuf[PCAP_ERRBUF_SIZE]; |
026 | |
027 | /* 获取本机设备列表 */ |
028 | if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) |
029 | { |
030 | fprintf (stderr, "Error in pcap_findalldevs: %s\n" , errbuf); |
031 | return 0; |
032 | } |
033 | |
034 | /* 打印列表 */ |
035 | for (d=alldevs; d; d=d->next) |
036 | { |
037 | printf ( "%d. %s" , ++i, d->name); |
038 | if (d->description) |
039 | printf ( " (%s)\n" , d->description); |
040 | else |
041 | printf ( " (No description available)\n" ); |
042 | } |
043 | |
044 | if (i==0) |
045 | { |
046 | printf ( "\nNo interfaces found! Make sure WinPcap is installed.\n" ); |
047 | return -1; |
048 | } |
049 | |
050 | printf ( "Enter the interface number (1-%d):" ,i); |
051 | scanf ( "%d" , &inum); |
052 | |
053 | if (inum < 1 || inum > i) |
054 | { |
055 | printf ( "\nInterface number out of range.\n" ); |
056 | /* 释放设备列表 */ |
057 | pcap_freealldevs(alldevs); |
058 | return -1; |
059 | } |
060 | |
061 | /* 跳转到选中的适配器 */ |
062 | for (d=alldevs, i=0; i< inum-1 ;d=d->next, i++); |
063 | |
064 | /* 打开设备 */ |
065 | if ( (adhandle= pcap_open(d->name, // 设备名 |
066 | 65536, // 65535保证能捕获到不同数据链路层上的每个数据包的全部内容 |
067 | PCAP_OPENFLAG_PROMISCUOUS, // 混杂模式 |
068 | 1000, // 读取超时时间 |
069 | NULL, // 远程机器验证 |
070 | errbuf // 错误缓冲池 |
071 | ) ) == NULL) |
072 | { |
073 | fprintf (stderr, "\nUnable to open the adapter. %s is not supported by WinPcap\n" , d->name); |
074 | /* 释放设备列表 */ |
075 | pcap_freealldevs(alldevs); |
076 | return -1; |
077 | } |
078 | |
079 | printf ( "\nlistening on %s...\n" , d->description); |
080 | |
081 | /* 释放设备列表 */ |
082 | pcap_freealldevs(alldevs); |
083 | |
084 | /* 开始捕获 */ |
085 | pcap_loop(adhandle, 0, packet_handler, NULL); |
086 | |
087 | return 0; |
088 | } |
089 |
090 |
091 | /* 每次捕获到数据包时,libpcap都会自动调用这个回调函数 */ |
092 | void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) |
093 | { |
094 | struct tm *ltime; |
095 | char timestr[16]; |
096 | time_t local_tv_sec; |
097 | if (ktime == 0) |
098 | { |
099 | timebegin = header->ts; |
100 | timeend = header->ts; |
101 | ktime++; |
102 | return ; |
103 | } |
104 | timeend = header->ts; |
105 | /* 将时间戳转换成可识别的格式 */ |
106 | local_tv_sec = header->ts.tv_sec; |
107 | ltime= localtime (&local_tv_sec); |
108 | strftime ( timestr, sizeof timestr, "%H:%M:%S" , ltime); |
109 | //printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len); |
110 | |
111 | Capturelen += header->caplen; |
112 | /* |
113 | float timeSec = (float)header->ts.tv_sec + (header->ts.tv_usec/1000); |
114 | printf("sec: %d , microsec %d \n",header->ts.tv_sec,header->ts.tv_usec); |
115 | printf("len: %d , time: %.1f \n",Capturelen,timeSec); |
116 | */ |
117 | int timeSec = (timeend.tv_sec-timebegin.tv_sec)*1000000 + timeend.tv_usec - timebegin.tv_usec; |
118 | |
119 | /* |
120 |
121 | */ |
122 | if (timeSec > 1000000) |
123 | { |
124 | float speed = ( float )Capturelen/timeSec*1000000; |
125 | //printf("speed is: %.1f B/s \n",speed); |
126 | |
127 | if (speed>=0.0 && speed <1024.0) |
128 | { |
129 | printf ( "speed is: %.1f B/s \n" ,speed); |
130 | } else if (speed>=1024.0 && speed< 1024*1024) |
131 | { |
132 | printf ( "speed is: %.1f KB/s \n" ,speed/1024); |
133 | } else if (speed>=1024*1024 && speed< 1024*1024*1024) |
134 | { |
135 | printf ( "speed is: %.1f MB/s \n" ,speed/1024/1024); |
136 | } |
137 | timebegin = timeend; |
138 | Capturelen = 0; |
139 |
140 | } |
141 | } |
0则评论给“网卡流量探测器”