修改了一个抓包的程序(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线程来分析数据包,基本足够了。 |
文章评论(0条评论)
登录后参与讨论