主要原理很简单,就是用一个队列(Queue)对高峰流量做一下缓冲,先存下来再慢慢分析。计算机专业的人应该就容易了,数据结构有讲。
整个程序代码比较长就不贴了,把队列代码贴在下面吧,放在网上的比硬盘的还是方便一点,随时可以查阅,以备不时之需。
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <malloc.h>
-
#include <string.h>
-
typedef struct _Node
-
{
-
int data_len; // 存储在节点中的数据长度
-
char *data; // 存储在节点中的数据
-
struct _Node *next; // 队列中的下一个节点地址
-
}NODE;
-
typedef struct _Queue
-
{
-
NODE *head; // 队列的头部
-
NODE *end; // 队列的尾部
-
int count; // 队列长度
-
}QUEUE;
-
bool InitQueue ( QUEUE *queue )
-
{
-
if ( NULL == queue )
-
{
-
return false;
-
}
-
queue->head = NULL;
-
queue->end = NULL;
-
queue->count = 0;
-
return true;
-
}
-
// 在队列中插入节点
-
bool Enqueue ( QUEUE *queue, char *queue_data, int data_len )
-
{
-
if ( NULL == queue || NULL == queue_data )
-
{
-
return false;
-
}
-
// 开辟新节点
-
NODE *new_node = (NODE * ) malloc ( sizeof (NODE ) );
-
if ( NULL == new_node )
-
{
-
return false;
-
}
-
// 开辟空间存储数据
-
new_node->data = ( char * ) malloc ( data_len );
-
if ( NULL == new_node->data )
-
{
-
return false;
-
}
-
memcpy ( new_node->data, queue_data, data_len );
-
new_node->next = NULL;
-
new_node->data_len = data_len;
-
// 如果队列为空,则新节点即是头部,也是尾部
-
if ( queue->head == NULL )
-
{
-
queue->head = new_node;
-
queue->end = new_node;
-
}
-
else
-
{
-
// 如果队列不为空,将此节点连接到队列的尾部
-
queue->end->next = new_node;
-
// 队列新尾部指向此节点
-
queue->end = new_node;
-
}
-
queue->count ++;
-
return true;
-
}
-
// 从队列中读出一个节点
-
NODE *Dequeue ( QUEUE *queue )
-
{
-
if ( NULL == queue )
-
{
-
return NULL;
-
}
-
// 如果队列为空,则无数据可从数列读出,直接返回
-
if ( NULL == queue->head )
-
{
-
return NULL;
-
}
-
// 保存队列首节点
-
NODE *node_tmp = queue->head;
-
// 将首节点的下一个节点(第二个节点)设置为首节点,即删除了首节点
-
queue->head = node_tmp->next;
-
// 如果新首节点为空,则队列为空
-
if ( NULL == queue->head )
-
{
-
queue->end = NULL;
-
}
-
queue->count --;
-
return node_tmp;
-
}
-
// 释放队列所有内存
-
void FreeQueue ( QUEUE *queue )
-
{
-
if ( !queue )
-
{
-
return;
-
}
-
NODE *tmp_node1 = queue->head;
-
while ( tmp_node1 )
-
{
-
NODE *tmp_node2 = tmp_node1;
-
free ( tmp_node1->data );
-
free ( tmp_node1 );
-
tmp_node1->data = NULL;
-
tmp_node1 = NULL;
-
tmp_node1 = tmp_node2->next;
-
}
-
}
这样没抓到一个包,就压入到队列里面。流量较大的尖峰时刻时候队列会比较长,但是流量较小的时候队列就比较短了。服务器流量不会一直保持在顶峰,所以可以把部分过高的流量缓冲到流量较小的时候做分析,测试的时候发现确实稳定了很多。首先需要注意的是设置一个队列最大长度,必要的时候丢掉一些数据免得内存耗尽。另外一个是分析的时候可以多线程读取队列进行分析,这样速度会更快,只是做好线程的同步就好了,CreateMutex是最简单易行的了。我用5线程来分析数据包,基本足够了。