原创 修改了一个抓包的程序(c语言队列)

2008-11-5 16:11 3947 8 8 分类: 软件与OS

修改了一个抓包的程序(c语言队列)

05 年底写了个抓包的小工具,做某些方面的测试用。但是在大流量的时候,存在一些问题,经常会漏掉一些包没有分析,即使接到了预定义好的包,也没有办法作出某些响应。周末没事,就做了一些改写,主要原理很简单,就是用一个队列(Queue)对高峰流量做一下缓冲,先存下来再慢慢分析。读了计算机专业的人应该就容易了,数据结构有讲。我比较土一点,学经济的,只能自己根据C#的接口YY一个类似的。

      整个程序代码比较长就不贴了,把队列代码贴在下面吧,放在网上的比硬盘的还是方便一点,随时可以查阅,以备不时之需。    



   1. #include <stdio.h>
   2.  
   3. #include <stdlib.h>
   4.  
   5. #include <malloc.h>
   6.  
   7. #include <string.h>
   8.  
   9.  
  10.  
  11. typedef struct _Node
  12.  
  13. {
  14.  
  15.     int     data_len;       // 存储在节点中的数据长度
  16.  
  17.     char    *data;          // 存储在节点中的数据
  18.  
  19.     struct  _Node *next;    // 队列中的下一个节点地址
  20.  
  21. }NODE;
  22.  
  23.  
  24.  
  25. typedef struct _Queue
  26.  
  27. {
  28.  
  29.     NODE    *head;          // 队列的头部
  30.  
  31.     NODE    *end;           // 队列的尾部
  32.  
  33.     int     count;          // 队列长度
  34.  
  35. }QUEUE;
  36.  
  37.  
  38.  
  39. bool InitQueue( QUEUE *queue )
  40.  
  41. {
  42.  
  43.     if( NULL == queue )
  44.  
  45.     {
  46.  
  47.         return false;
  48.  
  49.     }
  50.  
  51.  
  52.  
  53.     queue->head = NULL;
  54.  
  55.     queue->end = NULL;
  56.  
  57.     queue->count = 0;
  58.  
  59.  
  60.  
  61.     return true;
  62.  
  63. }
  64.  
  65.  
  66.  
  67. // 在队列中插入节点
  68.  
  69. bool Enqueue( QUEUE *queue, char *queue_data, int data_len )
  70.  
  71. {
  72.  
  73.     if( NULL == queue || NULL == queue_data )
  74.  
  75.     {
  76.  
  77.         return false;
  78.  
  79.     }
  80.  
  81.  
  82.  
  83.     // 开辟新节点
  84.  
  85.     NODE *new_node = (NODE *)malloc( sizeof(NODE) );
  86.  
  87.     if( NULL == new_node )
  88.  
  89.     {
  90.  
  91.         return false;
  92.  
  93.     }
  94.  
  95.  
  96.  
  97.     // 开辟空间存储数据
  98.  
  99.     new_node->data = (char *)malloc( data_len );
100.  
101.     if( NULL == new_node->data )
102.  
103.     {
104.  
105.         return false;
106.  
107.     }
108.  
109.  
110.  
111.     memcpy( new_node->data, queue_data, data_len );
112.  
113.     new_node->next = NULL;
114.  
115.     new_node->data_len = data_len;
116.  
117.  
118.  
119.     // 如果队列为空,则新节点即是头部,也是尾部
120.  
121.     if( queue->head == NULL )
122.  
123.     {
124.  
125.         queue->head = new_node;
126.  
127.         queue->end = new_node;
128.  
129.     }
130.  
131.     else
132.  
133.     {
134.  
135.         // 如果队列不为空,将此节点连接到队列的尾部
136.  
137.         queue->end->next = new_node;
138.  
139.  
140.  
141.         // 队列新尾部指向此节点
142.  
143.         queue->end = new_node;
144.  
145.     }
146.  
147.  
148.  
149.     queue->count ++;
150.  
151.     return true;
152.  
153. }
154.  
155.  
156.  
157. // 从队列中读出一个节点
158.  
159. NODE *Dequeue( QUEUE *queue )
160.  
161. {
162.  
163.     if( NULL == queue )
164.  
165.     {
166.  
167.         return NULL;
168.  
169.     }
170.  
171.  
172.  
173.     // 如果队列为空,则无数据可从数列读出,直接返回
174.  
175.     if( NULL == queue->head )
176.  
177.     {
178.  
179.         return NULL;
180.  
181.     }
182.  
183.  
184.  
185.     // 保存队列首节点
186.  
187.     NODE *node_tmp = queue->head;
188.  
189.  
190.  
191.     // 将首节点的下一个节点(第二个节点)设置为首节点,即删除了首节点
192.  
193.     queue->head = node_tmp->next;
194.  
195.  
196.  
197.     // 如果新首节点为空,则队列为空
198.  
199.     if( NULL == queue->head )
200.  
201.     {
202.  
203.         queue->end = NULL;
204.  
205.     }
206.  
207.  
208.  
209.     queue->count --;
210.  
211.     return node_tmp;
212.  
213. }
214.  
215.  
216.  
217. // 释放队列所有内存
218.  
219. void FreeQueue( QUEUE *queue )
220.  
221. {
222.  
223.     if( queue )
224.  
225.     {
226.  
227.         return;
228.  
229.     }
230.  
231.  
232.  
233.     NODE *tmp_node1 = queue->head;
234.  
235.     while( tmp_node1 )
236.  
237.     {
238.  
239.         NODE *tmp_node2 = tmp_node1;
240.  
241.  
242.  
243.         free( tmp_node1->data );
244.  
245.         free( tmp_node1 );
246.  
247.  
248.  
249.         tmp_node1->data = NULL;
250.  
251.         tmp_node1 = NULL;
252.  
253.  
254.  
255.         tmp_node1 = tmp_node2->next;
256.  
257.     }
258.  
259. }
260.  
261.  

      这样没抓到一个包,就压入到队列里面。流量较大的尖峰时刻时候队列会比较长,但是流量较小的时候队列就比较短了。服务器流量不会一直保持在顶峰,所以可以把部分过高的流量缓冲到流量较小的时候做分析,测试的时候发现确实稳定了很多。首先需要注意的是设置一个队列最大长度,必要的时候丢掉一些数据免得内存耗尽。另外一个是分析的时候可以多线程读取队列进行分析,这样速度会更快,只是做好线程的同步就好了,CreateMutex是最简单易行的了。我用5线程来分析数据包,基本足够了。
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
8
关闭 站长推荐上一条 /3 下一条