高手指导!!大侠们帮帮我呀
本人写了一小段代码,主要运用于数据包捕获分析中,通过libnids可以采用到需要数据数据包,数据包重组后的,但每个数据包是顺序到来的,由于大部分采用gzip编码格式,需要将所有的数据包收齐后,再解压数据,但我想不到一个好的办法将数据收齐后处理,采用了一个全局内存,但感觉不合理,因为每次TCP连接都会调用队列,写文件好像也差不多,不知道证明办呢。采用全局内存时,程序结尾的地方会出错,不是很清楚原因
/* * ===================================================================================== * * Filename: test_3.c * * Description: * * Version: 1.0 * Created: 05/23/2012 08:37:07 PM * Revision: none * Compiler: gcc * * Author: YOUR NAME (), * Company: * * ===================================================================================== */#include <stdio.h>#include <stdlib.h>#include <string.h>char * buf = NULL; //用于收齐各个数据包的数据,当报文头的数据长度等于各个包的数据长度时就证明收齐了所有数据struct Node{ char * data; int len; int total_len; struct Node * next; struct Node * prev; }; typedef struct Node QNode; QNode * head; void init_queue(){ printf(".....init_queue....\n"); head = malloc(sizeof(QNode)); buf = malloc(65536); memset(buf, 0, 65536); head->data = NULL; head->len = 0; head->total_len = 0; head->next = NULL; head->prev = NULL; } int add_item(char * data,int size){ QNode * temp = malloc(sizeof(QNode)); temp->data = malloc(size); memset(temp->data, 0, size); memcpy(temp->data, data, size); temp->next = NULL; temp->prev = NULL; temp->len = size; if( head->next == NULL ) { head->next = temp; temp->prev = head; head->len++; return ; } QNode * p = head; while( p->next) { p = p->next; } p->next = temp; temp->prev = p; head->len++; return ; }void del_item(){ QNode * temp = head; QNode * p = head; QNode * q; char* t = buf; if( head->next == NULL ) { printf("The queue is empty!!\n"); return ; } printf("There is %d items.\n", head->total_len); while( p->next ) { q = p->next; p = p->next; printf("%s\n", p->data); memcpy(t, p->data, p->len); t = t + p->len; free(q); }}int QueueLength(){ QNode * p = head; int i = 0; while(p->next){ i++; p = p->next; } return i; }void ClearQueue(){ QNode * p, *q; int i; p= head->next; head->next = NULL; for(i = 0; i< head->total_len; i++){ printf("%c", buf[i]); } while( p ) { q = p; p = p->next; free(q); }}int main(int argc, char *argv[]){ init_queue(); char * data = "I am a student.";//假设数据包1 char * data1 = "I am a student1"; //假设数据包2 char * data2 = "I am a student2";//假设数据包3 char * data3 = "I am a student3"; //假设数据包4 head->total_len = strlen(data)+strlen(data1)+strlen(data2)+strlen(data3); add_item(data, strlen(data)); add_item(data1, strlen(data1)); add_item(data2, strlen(data2)); add_item(data3, strlen(data3)); del_item(); ClearQueue(); //free(buf);在这里释放全局内存会报内存出错,求指导}/* zpipe.c: example of proper use of zlib's inflate() and deflate() Not copyrighted -- provided to the public domain Version 1.4 11 December 2005 Mark Adler *//* Version history: 1.0 30 Oct 2004 First version 1.1 8 Nov 2004 Add void casting for unused return values Use switch statement for inflate() return values 1.2 9 Nov 2004 Add assertions to document zlib guarantees 1.3 6 Apr 2005 Remove incorrect assertion in inf() 1.4 11 Dec 2005 Add hack to avoid MSDOS end-of-line conversions Avoid some compiler warnings for input and output buffers */#include <stdio.h>#include <string.h>#include <assert.h>#include "zlib.h"#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)# include <fcntl.h># include <io.h># define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)#else# define SET_BINARY_MODE(file)#endif#define CHUNK 16384/* Compress from file source to file dest until EOF on source. def() returns Z_OK on success, Z_MEM_ERROR if memory could not be allocated for processing, Z_STREAM_ERROR if an invalid compression level is supplied, Z_VERSION_ERROR if the version of zlib.h and the version of the library linked do not match, or Z_ERRNO if there is an error reading or writing the files. */int def(FILE *source, FILE *dest, int level){ int ret, flush; unsigned have; z_stream strm; unsigned char in[CHUNK]; unsigned char out[CHUNK]; /* allocate deflate state */ strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; ret = deflateInit2(&strm, level, Z_DEFLATED, 26, 9, Z_DEFAULT_STRATEGY); if (ret != Z_OK) return ret; /* compress until end of file */ do { strm.avail_in = fread(in, 1, CHUNK, source); if (ferror(source)) { (void)deflateEnd(&strm); return Z_ERRNO; } flush = feof(source) ? Z_FINISH : Z_NO_FLUSH; strm.next_in = in; /* run deflate() on input until output buffer not full, finish compression if all of source has been read in */ do { strm.avail_out = CHUNK; strm.next_out = out; ret = deflate(&strm, flush); /* no bad return value */ assert(ret != Z_STREAM_ERROR); /* state not clobbered */ have = CHUNK - strm.avail_out; if (fwrite(out, 1, have, dest) != have || ferror(dest)) { (void)deflateEnd(&strm); return Z_ERRNO; } } while (strm.avail_out == 0); assert(strm.avail_in == 0); /* all input will be used */ /* done when last data in file processed */ } while (flush != Z_FINISH); assert(ret == Z_STREAM_END); /* stream will be complete */ /* clean up and return */ (void)deflateEnd(&strm); return Z_OK;}/* Decompress from file source to file dest until stream ends or EOF. inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be allocated for processing, Z_DATA_ERROR if the deflate data is invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and the version of the library linked do not match, or Z_ERRNO if there is an error reading or writing the files. */int inf(FILE *source, FILE *dest){ int ret; unsigned have; z_stream strm; unsigned char in[CHUNK]; unsigned char out[CHUNK]; /* allocate inflate state */ strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = 0; strm.next_in = Z_NULL; ret = inflateInit2(&strm, 26); if (ret != Z_OK) return ret; /* decompress until deflate stream ends or end of file */ do { strm.avail_in = fread(in, 1, CHUNK, source); if (ferror(source)) { (void)inflateEnd(&strm); return Z_ERRNO; } if (strm.avail_in == 0) break; strm.next_in = in; /* run inflate() on input until output buffer not full */ do { strm.avail_out = CHUNK; strm.next_out = out; ret = inflate(&strm, Z_NO_FLUSH); assert(ret != Z_STREAM_ERROR); /* state not clobbered */ switch (ret) { case Z_NEED_DICT: ret = Z_DATA_ERROR; /* and fall through */ case Z_DATA_ERROR: case Z_MEM_ERROR: (void)inflateEnd(&strm); return ret; } have = CHUNK - strm.avail_out; if (fwrite(out, 1, have, dest) != have || ferror(dest)) { (void)inflateEnd(&strm); return Z_ERRNO; } } while (strm.avail_out == 0); /* done when inflate() says it's done */ } while (ret != Z_STREAM_END); /* clean up and return */ (void)inflateEnd(&strm); return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;}/* report a zlib or i/o error */void zerr(int ret){ fputs("zpipe: ", stderr); switch (ret) { case Z_ERRNO: if (ferror(stdin)) fputs("error reading stdin\n", stderr); if (ferror(stdout)) fputs("error writing stdout\n", stderr); break; case Z_STREAM_ERROR: fputs("invalid compression level\n", stderr); break; case Z_DATA_ERROR: fputs("invalid or incomplete deflate data\n", stderr); break; case Z_MEM_ERROR: fputs("out of memory\n", stderr); break; case Z_VERSION_ERROR: fputs("zlib version mismatch!\n", stderr); }}/* compress or decompress from stdin to stdout */int main(int argc, char **argv){ int ret; /* avoid end-of-line conversions */ SET_BINARY_MODE(stdin); SET_BINARY_MODE(stdout); if (argc == 1) { FILE *fin = fopen("test.txt", "wb+"); int i; for (i = 0; i != 16384; ++ i) { fwrite("a", 1, 1, fin); } fseek(fin, 0, SEEK_SET); SET_BINARY_MODE(fin); def(fin, stdout, 5); } else { inf(stdin, stdout); } return 0;}