在好例子网,分享、交流、成长!
您当前所在位置:首页C/C++ 开发实例Android手机应用开发 → c++ 网络流量统计 示例源码

c++ 网络流量统计 示例源码

Android手机应用开发

下载此实例
  • 开发语言:C/C++
  • 实例大小:7.54KB
  • 下载次数:28
  • 浏览次数:1244
  • 发布时间:2017-12-27
  • 实例类别:Android手机应用开发
  • 发 布 人:DOGON
  • 文件格式:.cpp
  • 所需积分:2
 相关标签: a

实例介绍

【实例简介】网络课程设计流量统计,网络流量统计课设
【实例截图】

【核心代码】

#include "pcap.h"  
#include<remote-ext.h>
#ifndef WIN32
#include <sys/socket.h>
#include <netinet/in.h>
#else
#include <winsock.h>
#endif
#include<conio.h>
#include<time.h>


/*全局变量*/
/*=====================================================*/
int num_packet = 0;			//统计的数据包个数
pcap_t *adhandle;			
//struct pcap_stat pkt_stat;
struct bpf_program fcode;
pcap_if_t *alldevs, *d;
char errbuf[PCAP_ERRBUF_SIZE];
u_int netmask;


/*=====================================================*/

/* 4字节的IP地址 */
typedef struct ip_address{
	u_char byte1;
	u_char byte2;
	u_char byte3;
	u_char byte4;
	
}ip_address;

/*ip链表*/
typedef struct ip_link{
	int number=1;
	u_char byte1;
	u_char byte2;
	u_char byte3;
	u_char byte4;
	struct ip_link *next;
}ip_link;
ip_link *head;

/* IPv4 首部 */
typedef struct ip_header{
	u_char  ver_ihl;        // 版本 (4 bits)   首部长度 (4 bits)  
	u_char  tos;            // 服务类型(Type of service)   
	u_short tlen;           // 总长(Total length)   
	u_short identification; // 标识(Identification)  
	u_short flags_fo;       // 标志位(Flags) (3 bits)   段偏移量(Fragment offset) (13 bits)  
	u_char  ttl;            // 存活时间(Time to live)  
	u_char  proto;          // 协议(Protocol)  
	u_short crc;            // 首部校验和(Header checksum)  
	ip_address  saddr;      // 源地址(Source address)  
	ip_address  daddr;      // 目的地址(Destination address)  
	u_int   op_pad;         // 选项与填充(Option   Padding)  
}ip_header;

/*设置一个观察变量表示是否暂停抓包*/
bool ispause = false;

/*监听键盘输入*/
DWORD WINAPI ThreadProc1(LPVOID lpParam)
{
	while (1)
	{
		if (_kbhit())		//检查是否有键盘输入
		{
			ispause = _getch() == 27;		//esc键			
		}
	}
}

/*将捕获的数据包的源ip加入链表*/
void add_link_ip(ip_address ip)
{
	ip_link *q=head;
	while (q->next != NULL)
	{
		q = q->next;
		if (q->byte1 == ip.byte1&&
			q->byte2 == ip.byte2&&
			q->byte3 == ip.byte3&&
			q->byte4 == ip.byte4)
		{
			q->number  ; 
			return;
		}

	}
	ip_link *p = (ip_link*)malloc(sizeof(ip_link));
	
	p->byte1 = ip.byte1;
	p->byte2 = ip.byte2;
	p->byte3 = ip.byte3;
	p->byte4 = ip.byte4;
	p->number = 1;
	p->next = head->next;
	head->next = p;
	//printf("添加一条数据\n");

}

/*获取网卡列表*/
void get_adapter()
{
	
	if (pcap_findalldevs(&alldevs, errbuf) == -1)//无法找到网卡列表
	{
		fprintf(stderr, "error in pcap_findalldevs: %s\n", errbuf);
		exit(1);
	}
	
}

/*输出网卡信息*/
int printf_adapter()
{
	u_int32_t net_ip, net_mask;
	struct in_addr net_ip_address, net_mask_address;//网卡IP信息,在pcap.h里面有定义
	int num=0;
	char *net_ip_string, *net_mask_string;
	pcap_if_t *d;
	/* 打印列表*/
	for (d = alldevs; d; d = d->next)
	{
		printf("%d.\n %s",   num, d->name);

		printf("\nDescription: %s\n", d->description);
		pcap_lookupnet(d->name, &net_ip, &net_mask, errbuf);

		net_ip_address.s_addr = net_ip;
		net_ip_string = inet_ntoa(net_ip_address);//format
		printf("网络地址: %s \n", net_ip_string);

		net_mask_address.s_addr = net_mask;
		net_mask_string = inet_ntoa(net_mask_address);//format
		printf("子网掩码: %s \n", net_mask_string);
		printf("\n");
		
	}
	return num;
	if (num == 0)
	{
		printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
		return -1;
	}
}

/*设置网卡模式,获取网络地址和掩码地址*/
int get_address()
{
	/* 打开适配器 */
	if ((adhandle = pcap_open(d->name,  // 设备名  
		65536,     // 要捕捉的数据包的部分   
		// 65535保证能捕获到不同数据链路层上的每个数据包的全部内容  
		PCAP_OPENFLAG_PROMISCUOUS,         // 混杂模式  
		1000,      // 读取超时时间  
		NULL,      // 远程机器验证  
		errbuf     // 错误缓冲池  
		)) == NULL)
	{
		fprintf(stderr, "\nUnable to open the adapter. %s is not supported by WinPcap\n");
		/* 释放设备列表 */
		pcap_freealldevs(alldevs);
		return -1;
	}

	if (d->addresses != NULL)
		/* 获得接口第一个地址的掩码 */
		netmask = ((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;
	else
		/* 如果接口没有地址,那么我们假设一个C类的掩码 */
		netmask = 0xffffff;
}

/*选择网卡,跳转设备*/
int select_adapter(int i)
{
	int inum;
	printf("Enter the interface number (1-%d):", i);
	scanf("%d", &inum);

	if (inum < 1 || inum > i)
	{
		printf("\nInterface number out of range.\n");
		/* 释放设备列表 */
		pcap_freealldevs(alldevs);
		return -1;
	}
	/* 跳转到已选设备 */
	for (d = alldevs, i = 0; i < inum - 1; d = d->next, i  );
}

/*设置过滤器*/  
int filter()
{
	char packet_filter[1000];         //设置过滤规则
	printf("请输入过滤规则\n");
	getchar();
	gets(packet_filter);
	//printf("%s", packet_filter);

	//编译过滤器  
	if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) < 0)
	{
		fprintf(stderr, "\nUnable to compile the packet filter. Check the syntax.\n");
		/* 释放设备列表 */
		pcap_freealldevs(alldevs);
		return -1;
	}

	//设置过滤器  
	if (pcap_setfilter(adhandle, &fcode) < 0)
	{
		fprintf(stderr, "\nError setting the filter.\n");
		/* 释放设备列表 */
		pcap_freealldevs(alldevs);
		return -1;
	}
}

/*将统计数据输出*/
void printf_link_ip(ip_link *head)
{
	if (head == NULL)
	{
		//	printf("tututu");
		return;
	}

	ip_link *q = head;
	printf("========================================\n");
	printf("|共接收%d数据包\t\t\t|\n", num_packet);
	printf("|\t源地址\t\t\t|数量\n");
	while (q->next != NULL)
	{

		printf("|\t%d.%d.%d.%d\t\t|", q->next->byte1, q->next->byte2, q->next->byte3, q->next->byte4);
		printf("%d个\n", q->next->number);
		q = q->next;
	}
	printf("========================================\n");
}

/* 回调函数,当收到每一个数据包时会被libpcap所调用 */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
	struct tm *ltime;
	char timestr[16];
	ip_header *ih;
	u_int ip_len;
	time_t local_tv_sec;

	if (ispause)
	{
		pcap_breakloop(adhandle);
		printf_link_ip(head);
		return;
	}
	/* 将时间戳转换成可识别的格式 */
	local_tv_sec = header->ts.tv_sec;
	ltime = localtime(&local_tv_sec);
	strftime(timestr, sizeof timestr, "%H:%M:%S", ltime);

	/* 打印数据包的时间戳和长度 */
	printf("%s.%.6d len:%d ", timestr, header->ts.tv_usec, header->len);

	/* 获得IP数据包头部的位置 */
	ih = (ip_header *)(pkt_data  
		14); //以太网头部长度  

	/* 打印IP地址 */
	printf("%d.%d.%d.%d -> %d.%d.%d.%d\n",
		ih->saddr.byte1,
		ih->saddr.byte2,
		ih->saddr.byte3,
		ih->saddr.byte4,
		ih->daddr.byte1,
		ih->daddr.byte2,
		ih->daddr.byte3,
		ih->daddr.byte4
		);	
	add_link_ip(ih->saddr);	
	num_packet  ;
}

int main()
{
	int inum;		//输入的网卡序号
	int i = 0;		//网卡序号		

	head = (ip_link*)malloc(sizeof(ip_link));	//初始化ip链表
	head->next = NULL;

	/*创建监听线程*/
	CreateThread(
		NULL,               // default security attributes
		0,                  // use default stack size  
		ThreadProc1,        // thread function 
		NULL,               // argument to thread function 
		0,                  // use default creation flags 
		NULL);			    // returns the thread identifier 
	/*获取网卡列表*/
	get_adapter();

	/*输出网卡列表,返回网卡数量*/
	i = printf_adapter();

	/*选择网卡*/
	select_adapter(i);

	/*设置网卡模式,获取网络地址和掩码地址*/
	get_address();

	/*设置过滤器*/
	filter();

	printf("\nlistening on %s...\n", d->description);

	/* 释放设备列表 */
	pcap_freealldevs(alldevs);

	/* 开始捕捉 */
	printf("\t时间\t 长度\t 源ip\t\t目的ip\n");
	pcap_loop(adhandle, 0, packet_handler, NULL); //数字表示抓几回包停止,0表示无限制

	//暂停函数
	rewind(stdin); getchar();

	return 0;
}

标签: a

实例下载地址

c++ 网络流量统计 示例源码

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

第 1 楼 Eason0909 发表于: 2018-01-31 10:07 00
运行不了,没有头文件pcap.h

支持(0) 盖楼(回复)

发表评论

(您的评论需要经过审核才能显示)

查看所有1条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警