//获得网卡流量信息 DWORD dwIfBufSize = 0; BOOL bRet; if(m_pMIT == NULL) m_pMIT = new MIB_IFTABLE[sizeof(MIB_IFTABLE)]; bRet = ::GetIfTable(m_pMIT,&dwIfBufSize,0); if(bRet == ERROR_INSUFFICIENT_BUFFER)//如果内存不足,则重新分配内存大小 { if(dwIfBufSize != NULL) delete [] m_pMIT; m_pMIT = new MIB_IFTABLE[dwIfBufSize]; } bRet = ::GetIfTable(m_pMIT,&dwIfBufSize,0); if (bRet == NO_ERROR) { if (m_pMIT->dwNumEntries <= 1) { //bResult = false; } else { __int64 i64TotalOutOctets = 0; __int64 i64TotalInOctets = 0; //多網卡 for(int i=0; i<(m_pMIT->dwNumEntries); i++) { if (m_pMIT->table[i].dwType <= 23) { //当前上传 i64TotalOutOctets += m_pMIT->table[i].dwOutOctets; //当前下载 i64TotalInOctets += m_pMIT->table[i].dwInOctets; //bResult = mit.table[i].dwOperStatus; //if (bResult) { //return true; } } } memset(szVal,0,sizeof(szVal)); if(m_oldUploadOctets != 0 && (i64TotalOutOctets > m_oldUploadOctets)) m_curUploadOctets = i64TotalOutOctets - m_oldUploadOctets; m_oldUploadOctets = i64TotalOutOctets; lengthToStr(m_curUploadOctets * 8,szVal); m_CapabilityDlgObj.GetDlgItem(IDC_STA_NETUPSPEED)->SetWindowText(szVal); //下载 memset(szVal,0,sizeof(szVal)); if(m_oldDownloadOctets != 0 && (i64TotalInOctets > m_oldDownloadOctets)) m_curDownloadOctets = i64TotalInOctets - m_oldDownloadOctets; m_oldDownloadOctets = i64TotalInOctets; lengthToStr(m_curDownloadOctets * 8,szVal); m_CapabilityDlgObj.GetDlgItem(IDC_STA_NETDNSPEED)->SetWindowText(szVal); } }
还有个wincap 的例子
#include "stdafx.h" #include <stdlib.h> #include <stdio.h> #include "include/pcap.h" #pragma comment(lib,"lib/Packet.lib") #pragma comment(lib,"lib/wpcap.lib") void usage(); void dispatcher_handler(u_char *, const struct pcap_pkthdr *, const u_char *); void _tmain(int argc, _TCHAR* argv[]) { pcap_t *fp; char errbuf[PCAP_ERRBUF_SIZE]; struct timeval st_ts; u_int netmask; struct bpf_program fcode; /* 检查命令行参数的合法性 */ /* 打开输出适配器 */ if((fp= pcap_open_live("\\Device\\NPF_{4C280CAF-B56F-467D-91E2-43F8C54B5BD2}"/*我的网卡名*/,100,1,1000,errbuf))==NULL) { fprintf(stderr,"\nUnable to open adapter %s.\n", errbuf); return; } /* 不用关心掩码,在这个过滤器中,它不会被使用 */ netmask=0xffffff; // 编译过滤器 if (pcap_compile(fp, &fcode, "ether proto 0x8864"/*我用的是ADSL这里是设置只接收PPPOE的包*/, 1, netmask) <0 ) { fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n"); /* 释放设备列表 */ return; } //设置过滤器 if (pcap_setfilter(fp, &fcode)<0) { fprintf(stderr,"\nError setting the filter.\n"); pcap_close(fp); /* 释放设备列表 */ return; } /* 将接口设置为统计模式 */ if (pcap_setmode(fp, MODE_STAT)<0) { fprintf(stderr,"\nError setting the mode.\n"); pcap_close(fp); /* 释放设备列表 */ return; } printf("NetWork traffic summary:\n"); /* 开始主循环 */ pcap_loop(fp, 0, dispatcher_handler, (PUCHAR)&st_ts); pcap_close(fp); return; } void dispatcher_handler(u_char *state, const struct pcap_pkthdr *header, const u_char *pkt_data) { struct timeval *old_ts = (struct timeval *)state; u_int delay; LARGE_INTEGER Bps,Pps; struct tm *ltime; char timestr[16]; time_t local_tv_sec; /* 以毫秒计算上一次采样的延迟时间 */ /* 这个值通过采样到的时间戳获得 */ delay=(header->ts.tv_sec - old_ts->tv_sec) * 1000000 - old_ts->tv_usec + header->ts.tv_usec; /* 获取每秒的比特数b/s */ Bps.QuadPart=(((*(LONGLONG*)(pkt_data + 8)) * 8 * 1000000) / (delay)); /* ^ ^ | | | | | | 将字节转换成比特 -- | | 延时是以毫秒表示的 -- */ /* 得到每秒的数据包数量 */ Pps.QuadPart=(((*(LONGLONG*)(pkt_data)) * 1000000) / (delay)); /* 将时间戳转化为可识别的格式 */ local_tv_sec = header->ts.tv_sec; ltime=localtime(&local_tv_sec); strftime( timestr, sizeof timestr, "%H:%M:%S", ltime); /* 打印时间戳*/ printf("%s ", timestr); /* 打印采样结果 */ printf("BPS=%I64u ", Bps.QuadPart); printf("PPS=%I64u\n", Pps.QuadPart); //存储当前的时间戳 old_ts->tv_sec=header->ts.tv_sec; old_ts->tv_usec=header->ts.tv_usec; } void usage() { printf("\nShows the TCP traffic load, in bits per second and packets per second.\nCopyright (C) 2002 Loris Degioanni.\n"); printf("\nUsage:\n"); printf("\t tcptop adapter\n"); printf("\t You can use \"WinDump -D\" if you don't know the name of your adapters.\n"); exit(0); }