hello world

          隨筆 - 2, 文章 - 63, 評論 - 0, 引用 - 0
          數據加載中……

          【轉】Zlib庫的安裝與使用

          在實際應用中經常會遇到要壓縮數據的問題,常見的壓縮格式有zip和rar,而 Linux下那就更多了,bz2,gz,xz什么的都有,單單Linux下的解壓和壓縮命令就有好多呢?沒有什么好不好的。查了資料,應該是zlib這個 比較簡單好用。應用也廣,所以就準備用這個了。

            下載Zlib庫,地址:?http://zlib.net /zlib128.zip 用wget下載,然后再用unzip解壓一下,然后就像一般軟件一樣 ./configure && make && make install .(注意要root權限)

            下面這個是安裝信息

          cp?libz.a? / usr / local / lib
          chmod?
          644 ? / usr / local / lib / libz.a
          cp?libz.so.
          1.2 . 8 ? / usr / local / lib
          chmod?
          755 ? / usr / local / lib / libz.so. 1.2 . 8
          cp?zlib.
          3 ? / usr / local / share / man / man3
          chmod?
          644 ? / usr / local / share / man / man3 / zlib. 3
          cp?zlib.pc?
          / usr / local / lib / pkgconfig
          chmod?
          644 ? / usr / local / lib / pkgconfig / zlib.pc
          cp?zlib.h?zconf.h?
          / usr / local / include
          chmod?
          644 ? / usr / local / include / zlib.h? / usr / local / include / zconf.h
            寫一個簡單的例子測試一下,注意編譯的時候要加入 -lz 這個庫
          #include? < stdio.h >
          #include?
          < zlib.h >

          int ?main( int ?argc, char ? ** args)
          {
          ????
          /* 原始數據 */
          ????unsigned?
          char ?strsrc[] = " 這些是測試數據。123456789?abcdefghigklmnopqrstuvwxyz\n\t\0abcdefghijklmnopqrstuvwxyz\n " ;? // 包含\0字符
          ????unsigned? char ?buf[ 1024 ] = { 0 };
          ????unsigned?
          char ?strdst[ 1024 ] = { 0 };
          ????unsigned?
          long ?srclen = sizeof (strsrc);
          ????unsigned?
          long ?buflen = sizeof (buf);
          ????unsigned?
          long ?dstlen = sizeof (strdst);
          ????
          int ?i;
          ????FILE?
          * ?fp;

          ????printf(
          " 源串: " );
          ????
          for (i = 0 ;i < srclen; ++ i)
          ????{
          ????????printf(
          " %c " ,strsrc[i]);
          ????}
          ????printf(
          " 原串長度為:%ld\n " ,srclen);

          ????printf(
          " 字符串預計算長度為:%ld\n " ,compressBound(srclen));
          ????
          // 壓縮
          ????compress(buf, & buflen,strsrc,srclen);
          ????printf(
          " 壓縮后實際長度為:%ld\n " ,buflen);
          ????
          // 解壓縮
          ????uncompress(strdst, & dstlen,buf,buflen);

          ????printf(
          " 目的串: " );
          ????
          for (i = 0 ;i < dstlen; ++ i)
          ????{
          ????????printf(
          " %c " ,strdst[i]);
          ????}

          ????
          return ? 0 ;
          }

            各個API

          ?1?//把源緩沖壓縮成到目的緩沖,一個函數就完成了
          ?2?int?compress?(Bytef?*dest,?uLongf?*destLen,?const?Bytef?*source,?uLong?sourceLen);
          ?3?
          ?4?//功能和compress函數一樣,多了一個參數可以指定壓縮質量和壓縮數度之間的關系(0-9)。要想得到高的壓縮比就要多花時間
          ?5?int?compress2?(Bytef?*dest,?uLongf?*destLen,const?Bytef?*source,?uLong?sourceLen,int?level);
          ?6?
          ?7?//計算需要的緩沖區長度.?假設你在壓縮之前就想知道你的產度為?sourcelen?的數據壓縮后有多大,?可調用這個函數計算一下,這個函數并不能得到精確的結果,但是它可以保證實際輸出長度肯定小于它計算出來的長度
          ?8?uLong?compressBound?(uLong?sourceLen);
          ?9?
          10?//解壓縮
          11?int?uncompress?(Bytef?*dest,?uLongf?*destLen,const?Bytef?*source,?uLong?sourceLen);

            處理gz后綴的壓縮文件。

            壓縮字符串到test.gz

          ?1?#include?<stdio.h>
          ?2?#include?<zlib.h>
          ?3?
          ?4?int?main(int?argc,char?**args)
          ?5?{
          ?6?????gzFile?file;
          ?7?????char?str[]="testtest";
          ?8?????file=gzopen("test.gz","wb");
          ?9?????if(NULL==file)
          10?????????perror("Can't?open?file");
          11?????gzsetparams(file,2,0);
          12?????gzwrite(file,str,sizeof(str));
          13?????gzclose(file);
          14?????return?0;
          15?}

            解壓test.gz

          ?1?#include?<stdio.h>
          ?2?#include?<zlib.h>
          ?3?
          ?4?int?main(int?argc,char?**args)
          ?5?{
          ?6?????gzFile?file;
          ?7?????char?str[64]={0};
          ?8?????file=gzopen("test.gz","rb");
          ?9?????if(NULL==file)
          10?????????perror("Can't?open?file");
          11?????gzread(file,str,10);
          12?????printf("從文件中讀取到的字符:%s.\n",str);
          13?????gzclose(file);
          14?????return?0;
          15?}

            對于test.gz這個文件如果不知道是否正確,可以使用系統命令zcat進 行查看。還有一個問題就是個壓縮包只能解壓出一個文件,是不可能存在多個文件的。 這是GZIP的特性決定了的。 通常,都是把多個文件用tar先壓成一個包,然后在gzip。這就是為什么下載的軟件源碼包大多都是 .tar.gz 這樣的格式。

            對于gz文件處理的API

          ?1?//注意下面介紹到的處理函數,跟一般文件的處理函數是相似的,效果也是差不多的。
          ?2?typedef?voidp?gzFile;
          ?3?
          ?4?//打開一個gzip文件進行讀/寫,mode和fopen("rb"或"?wb")一樣.也可以包括壓縮級別如:"wb9",或著一個策略"f"作為過濾數據"wb6f",?"h"是為了"huffman"?壓縮,如:"wb1h".gzopen用于讀一個沒有gzip格式的文件.gzread直接從沒有解壓縮的文件中讀數據.如果文件不能被打開或是沒有足夠的內存,gzopen將返回NULL.
          ?5?gzFile?gzopen(const?char?*path,const?char?*mode);
          ?6?
          ?7?//根據文件描述符打開一個gz文件
          ?8?gzFile?gzdopen?(int?fd,?const?char?*mode);
          ?9?
          10?//動態更新壓縮等級和壓縮格式?成功返回Z_OK?否則返回Z_STREAM_ERROR
          11?int?gzsetparams?(gzFile?file,?int?level,?int?strategy);
          12?
          13?//讀取所給的個數len字節。從壓縮文件中讀取解壓后的字符的個數。?如果file不是gzip格式,那么就讀取實際的字節個數,而不是解壓后的實際個數。成功返回所讀取的個數,0表示文件結束,-1表示錯誤。
          14?//英文原文?Reads?the?given?number?of?uncompressed?bytes?from?the?compressed?file.If?the?input?file?was?not?in?gzip?format,?gzread?copies?the?given?number?of?bytes?into?the?buffer.
          15?int?gzread?(gzFile?file,voidp?buf,?unsigned?int?len);
          16?
          17?//寫入所給長度的buf字符到file中?成功返回所寫入的字符個數,0表示寫入失敗
          18?int?gzwrite(gzFile?file,?voidp?buf,unsigned?int?len);
          19?
          20?//可以看到下面介紹到的所有函數都跟我們處理普通的文件一樣,把函數的gz換成f,是不是就熟悉了許多?大概就是這樣吧
          21?int?gzprintf(gzFile?file,const?char?*format,?);
          22?int?gzputs(gzFile?file,const?char?*s);
          23?char?*?gzgets(gzFile?file,?char?*buf,int?len);
          24?int?gzputc(gzFile?file,int?c);
          25?int?gzgetc(gzFile?file);
          26?int?gzungetc(int?c,gzFile?file);
          27?int?gzflush?(gzFile?file,int?flush);
          28?int?gzseek?(gzFile?file,z_off_t?offset,?int?whence);
          29?int?gzrewind(gzFile?file);
          30?z_off_t?gztell(gzFile?file);
          31?int?gzeof(gzFile?file);
          32?int?gzdirect(gzFile?file);
          33?int?gzclose(gzFile?file);
          34?const?char?*?gzerror(gzFile?file,?int?*errnum);
          35?void?gzclearerr(gzFile?file);

            計算校驗碼

          ?1?uLong?adler32?(uLong?adler,const?Bytef?*buf,?uInt?len);
          ?2?//使用方法如下
          ?3?uLong?adler=adler32(0L,Z_NULL,0);
          ?4?while(read_buffer(buffer,?length)?!=EOF)
          ?5?{
          ?6?????adler=adler32(adler,buffer,length);
          ?7?}
          ?8?if(adler?!=?original_adler)
          ?9?????error();
          10?
          11?uLong?crc32?(uLong?crc,const?Bytef?*buf,uInt?len);
          12?//使用方法如下
          13?uLong?crc?=?crc32(0L,Z_NULL,0);
          14?while(read_buffer(buffer,length)!=EOF)
          15?{
          16?????crc=crc32(crc,buffer,length);
          17?}
          18?if(crc?!=?original_crc)
          19?????error();
            最后是z_stream這個結構了
          ?1?typedef?struct?z_stream_s?{
          ?2?????Bytef????*next_in;??/*?next?input?byte?*/
          ?3?????uInt?????avail_in;??/*?number?of?bytes?available?at?next_in?*/
          ?4?????uLong????total_in;??/*?total?nb?of?input?bytes?read?so?far?*/
          ?5?
          ?6?????Bytef????*next_out;?/*?next?output?byte?should?be?put?there?*/
          ?7?????uInt?????avail_out;?/*?remaining?free?space?at?next_out?*/
          ?8?????uLong????total_out;?/*?total?nb?of?bytes?output?so?far?*/
          ?9?
          10?????char?????*msg;??????/*?last?error?message,?NULL?if?no?error?*/
          11?????struct?internal_state?FAR?*state;?/*?not?visible?by?applications?*/
          12?
          13?????alloc_func?zalloc;??/*?used?to?allocate?the?internal?state?*/
          14?????free_func??zfree;???/*?used?to?free?the?internal?state?*/
          15?????voidpf?????opaque;??/*?private?data?object?passed?to?zalloc?and?zfree?*/
          16?
          17?????int?????data_type;??/*?best?guess?about?the?data?type:?binary?or?text?*/
          18?????uLong???adler;??????/*?adler32?value?of?the?uncompressed?data?*/
          19?????uLong???reserved;???/*?reserved?for?future?use?*/
          20?}?z_stream;
          1?deflateInit()?+?deflate()?+?deflateEnd()
          2??//3個函數結合使用完成壓縮功能,具體用法看?example.c?的?test_deflate()函數.?其實compress()?函數內部就是用這3個函數實現的
          3??
          4??inflateInit()?+?inflate()?+?inflateEnd()
          5??//上面類似,完成解壓縮功能.
          6?
          7?

            下面給出一個example方面查看,了解函數的用法,不過一般應用程序用到上面的函數即可。

          ??1?/*?zpipe.c:?example?of?proper?use?of?zlib's?inflate()?and?deflate()
          ??2????Not?copyrighted?--?provided?to?the?public?domain
          ??3????Version?1.4??11?December?2005??Mark?Adler?*/
          ??4?
          ??5?/*?Version?history:
          ??6????1.0??30?Oct?2004??First?version
          ??7????1.1???8?Nov?2004??Add?void?casting?for?unused?return?values
          ??8??????????????????????Use?switch?statement?for?inflate()?return?values
          ??9????1.2???9?Nov?2004??Add?assertions?to?document?zlib?guarantees
          ?10????1.3???6?Apr?2005??Remove?incorrect?assertion?in?inf()
          ?11????1.4??11?Dec?2005??Add?hack?to?avoid?MSDOS?end-of-line?conversions
          ?12??????????????????????Avoid?some?compiler?warnings?for?input?and?output?buffers
          ?13??*/
          ?14?
          ?15?#include?<stdio.h>
          ?16?#include?<string.h>
          ?17?#include?<assert.h>
          ?18?#include?"zlib.h"
          ?19?
          ?20?#if?defined(MSDOS)?||?defined(OS2)?||?defined(WIN32)?||?defined(__CYGWIN__)
          ?21?#??include?<fcntl.h>
          ?22?#??include?<io.h>
          ?23?#??define?SET_BINARY_MODE(file)?setmode(fileno(file),?O_BINARY)
          ?24?#else
          ?25?#??define?SET_BINARY_MODE(file)
          ?26?#endif
          ?27?
          ?28?#define?CHUNK?16384
          ?29?
          ?30?/*?Compress?from?file?source?to?file?dest?until?EOF?on?source.
          ?31????def()?returns?Z_OK?on?success,?Z_MEM_ERROR?if?memory?could?not?be
          ?32????allocated?for?processing,?Z_STREAM_ERROR?if?an?invalid?compression
          ?33????level?is?supplied,?Z_VERSION_ERROR?if?the?version?of?zlib.h?and?the
          ?34????version?of?the?library?linked?do?not?match,?or?Z_ERRNO?if?there?is
          ?35????an?error?reading?or?writing?the?files.?*/
          ?36?int?def(FILE?*source,?FILE?*dest,?int?level)
          ?37?{
          ?38?????int?ret,?flush;
          ?39?????unsigned?have;
          ?40?????z_stream?strm;
          ?41?????unsigned?char?in[CHUNK];
          ?42?????unsigned?char?out[CHUNK];
          ?43?
          ?44?????/*?allocate?deflate?state?*/
          ?45?????strm.zalloc?=?Z_NULL;
          ?46?????strm.zfree?=?Z_NULL;
          ?47?????strm.opaque?=?Z_NULL;
          ?48?????ret?=?deflateInit(&strm,?level);
          ?49?????if?(ret?!=?Z_OK)
          ?50?????????return?ret;
          ?51?
          ?52?????/*?compress?until?end?of?file?*/
          ?53?????do?{
          ?54?????????strm.avail_in?=?fread(in,?1,?CHUNK,?source);
          ?55?????????if?(ferror(source))?{
          ?56?????????????(void)deflateEnd(&strm);
          ?57?????????????return?Z_ERRNO;
          ?58?????????}
          ?59?????????flush?=?feof(source)???Z_FINISH?:?Z_NO_FLUSH;
          ?60?????????strm.next_in?=?in;
          ?61?
          ?62?????????/*?run?deflate()?on?input?until?output?buffer?not?full,?finish
          ?63????????????compression?if?all?of?source?has?been?read?in?*/
          ?64?????????do?{
          ?65?????????????strm.avail_out?=?CHUNK;
          ?66?????????????strm.next_out?=?out;
          ?67?????????????ret?=?deflate(&strm,?flush);????/*?no?bad?return?value?*/
          ?68?????????????assert(ret?!=?Z_STREAM_ERROR);??/*?state?not?clobbered?*/
          ?69?????????????have?=?CHUNK?-?strm.avail_out;
          ?70?????????????if?(fwrite(out,?1,?have,?dest)?!=?have?||?ferror(dest))?{
          ?71?????????????????(void)deflateEnd(&strm);
          ?72?????????????????return?Z_ERRNO;
          ?73?????????????}
          ?74?????????}?while?(strm.avail_out?==?0);
          ?75?????????assert(strm.avail_in?==?0);?????/*?all?input?will?be?used?*/
          ?76?
          ?77?????????/*?done?when?last?data?in?file?processed?*/
          ?78?????}?while?(flush?!=?Z_FINISH);
          ?79?????assert(ret?==?Z_STREAM_END);????????/*?stream?will?be?complete?*/
          ?80?
          ?81?????/*?clean?up?and?return?*/
          ?82?????(void)deflateEnd(&strm);
          ?83?????return?Z_OK;
          ?84?}
          ?85?
          ?86?/*?Decompress?from?file?source?to?file?dest?until?stream?ends?or?EOF.
          ?87????inf()?returns?Z_OK?on?success,?Z_MEM_ERROR?if?memory?could?not?be
          ?88????allocated?for?processing,?Z_DATA_ERROR?if?the?deflate?data?is
          ?89????invalid?or?incomplete,?Z_VERSION_ERROR?if?the?version?of?zlib.h?and
          ?90????the?version?of?the?library?linked?do?not?match,?or?Z_ERRNO?if?there
          ?91????is?an?error?reading?or?writing?the?files.?*/
          ?92?int?inf(FILE?*source,?FILE?*dest)
          ?93?{
          ?94?????int?ret;
          ?95?????unsigned?have;
          ?96?????z_stream?strm;
          ?97?????unsigned?char?in[CHUNK];
          ?98?????unsigned?char?out[CHUNK];
          ?99?
          100?????/*?allocate?inflate?state?*/
          101?????strm.zalloc?=?Z_NULL;
          102?????strm.zfree?=?Z_NULL;
          103?????strm.opaque?=?Z_NULL;
          104?????strm.avail_in?=?0;
          105?????strm.next_in?=?Z_NULL;
          106?????ret?=?inflateInit(&strm);
          107?????if?(ret?!=?Z_OK)
          108?????????return?ret;
          109?
          110?????/*?decompress?until?deflate?stream?ends?or?end?of?file?*/
          111?????do?{
          112?????????strm.avail_in?=?fread(in,?1,?CHUNK,?source);
          113?????????if?(ferror(source))?{
          114?????????????(void)inflateEnd(&strm);
          115?????????????return?Z_ERRNO;
          116?????????}
          117?????????if?(strm.avail_in?==?0)
          118?????????????break;
          119?????????strm.next_in?=?in;
          120?
          121?????????/*?run?inflate()?on?input?until?output?buffer?not?full?*/
          122?????????do?{
          123?????????????strm.avail_out?=?CHUNK;//CHUNK=128K
          124?????????????strm.next_out?=?out;
          125?????????????ret?=?inflate(&strm,?Z_NO_FLUSH);
          126?????????????assert(ret?!=?Z_STREAM_ERROR);??/*?state?not?clobbered?*/
          127?????????????switch?(ret)?{
          128?????????????case?Z_NEED_DICT:
          129?????????????????ret?=?Z_DATA_ERROR;?????/*?and?fall?through?*/
          130?????????????case?Z_DATA_ERROR:
          131?????????????case?Z_MEM_ERROR:
          132?????????????????(void)inflateEnd(&strm);
          133?????????????????return?ret;
          134?????????????}
          135?????????????have?=?CHUNK?-?strm.avail_out;
          136?????????????if?(fwrite(out,?1,?have,?dest)?!=?have?||?ferror(dest))?{
          137?????????????????(void)inflateEnd(&strm);
          138?????????????????return?Z_ERRNO;
          139?????????????}
          140?????????}?while?(strm.avail_out?==?0);
          141?
          142?????????/*?done?when?inflate()?says?it's?done?*/
          143?????}?while?(ret?!=?Z_STREAM_END);
          144?
          145?????/*?clean?up?and?return?*/
          146?????(void)inflateEnd(&strm);
          147?????return?ret?==?Z_STREAM_END???Z_OK?:?Z_DATA_ERROR;
          148?}
          149?
          150?/*?report?a?zlib?or?i/o?error?*/
          151?void?zerr(int?ret)
          152?{
          153?????fputs("zpipe:?",?stderr);
          154?????switch?(ret)?{
          155?????case?Z_ERRNO:
          156?????????if?(ferror(stdin))
          157?????????????fputs("error?reading?stdin\n",?stderr);
          158?????????if?(ferror(stdout))
          159?????????????fputs("error?writing?stdout\n",?stderr);
          160?????????break;
          161?????case?Z_STREAM_ERROR:
          162?????????fputs("invalid?compression?level\n",?stderr);
          163?????????break;
          164?????case?Z_DATA_ERROR:
          165?????????fputs("invalid?or?incomplete?deflate?data\n",?stderr);
          166?????????break;
          167?????case?Z_MEM_ERROR:
          168?????????fputs("out?of?memory\n",?stderr);
          169?????????break;
          170?????case?Z_VERSION_ERROR:
          171?????????fputs("zlib?version?mismatch!\n",?stderr);
          172?????}
          173?}
          174?
          175?/*?compress?or?decompress?from?stdin?to?stdout?*/
          176?int?main(int?argc,?char?**argv)
          177?{
          178?????int?ret;
          179?
          180?????/*?avoid?end-of-line?conversions?*/
          181?????SET_BINARY_MODE(stdin);
          182?????SET_BINARY_MODE(stdout);
          183?
          184?????/*?do?compression?if?no?arguments?*/
          185?????if?(argc?==?1)?{
          186?????????ret?=?def(stdin,?stdout,?Z_DEFAULT_COMPRESSION);
          187?????????if?(ret?!=?Z_OK)
          188?????????????zerr(ret);
          189?????????return?ret;
          190?????}
          191?
          192?????/*?do?decompression?if?-d?specified?*/
          193?????else?if?(argc?==?2?&&?strcmp(argv[1],?"-d")?==?0)?{
          194?????????ret?=?inf(stdin,?stdout);
          195?????????if?(ret?!=?Z_OK)
          196?????????????zerr(ret);
          197?????????return?ret;
          198?????}
          199?
          200?????/*?otherwise,?report?usage?*/
          201?????else?{
          202?????????fputs("zpipe?usage:?zpipe?[-d]?<?source?>?dest\n",?stderr);
          203?????????return?1;
          204?????}
          205?}

            接下來給出一個實例來了解一下gzip。?

            Web服務器實現gzip壓縮發送

          ??1?#include?<string.h>
          ??2?#include?<stdio.h>
          ??3?#include?<stdlib.h>
          ??4?#include?<errno.h>
          ??5?#include?<sys/types.h>
          ??6?#include?<sys/socket.h>
          ??7?#include?<netinet/in.h>
          ??8?#include?<arpa/inet.h>
          ??9?#include?<unistd.h>
          ?10?#include?<signal.h>
          ?11?#include?<zlib.h>
          ?12?#include?<zconf.h>
          ?13?
          ?14?void?app_exit();
          ?15?int?socket_listen(u_short?port);
          ?16?void?send_http_head(int?clifd);
          ?17?void?put_long?(unsigned?char?*string,?unsigned?long?x);
          ?18?int?gzip_http_buffer(int?clifd,char?*msg,int?len);
          ?19?
          ?20?
          ?21?int?sockfd;
          ?22?int?main(int?argc,char?**args)
          ?23?{
          ?24?????struct?sockaddr_in?cli_sin;
          ?25?????socklen_t?cli_len=sizeof(cli_sin);
          ?26?????int?clifd;
          ?27?????char?buf[4096];
          ?28?????char?msg[4096]="<br><br><h1>Reage?Web?Server?gzip?support?text!</h1><br/><h1><a?href?=?\"http://wunaozai.cnblogs.com\">Reage?blog</a>";
          ?29?
          ?30?????signal(SIGINT,app_exit);
          ?31?????sockfd=socket_listen(8080);
          ?32?????while(1)
          ?33?????{
          ?34?????????clifd=accept(sockfd,(struct?sockaddr?*)&cli_sin,&cli_len);
          ?35?????????printf("連接進來的IP:%s:%u\n",inet_ntoa(cli_sin.sin_addr),ntohs(cli_sin.sin_port));
          ?36?????????read(clifd,buf,4096);
          ?37?????????printf("%s\n",buf);
          ?38?????????send_http_head(clifd);
          ?39?????????gzip_http_buffer(clifd,msg,strlen(msg));
          ?40?
          ?41?????????close(clifd);
          ?42?????}
          ?43?????close(sockfd);
          ?44?????return?0;
          ?45?}
          ?46?
          ?47?void?put_long?(unsigned?char?*string,?unsigned?long?x)//對于gzip后面的兩個字節進行位填充,這里應該是處理大端與小端
          ?48?{
          ?49?????string[0]?=?(x?&?0xff);
          ?50?????string[1]?=?((x?>>?8)?&?0xff)?;
          ?51?????string[2]?=?((x?>>?16)?&?0xff)?;
          ?52?????string[3]?=?((x?>>?24)?&?0xff);
          ?53?}
          ?54?/*
          ?55??*?對要發送的msg里面的字符進行壓縮發送
          ?56??*?gzip格式:?http://www.cnblogs.com/witxjp/archive/2003/12/17/1986210.html
          ?57??*?*/
          ?58?static?const?char?gzip_header[10]={0x1f,0x8b,0x08,0,0,0,0,0,0,0x03};
          ?59?int?gzip_http_buffer(int?clifd,char?*msg,int?len)
          ?60?{
          ?61?????z_stream?stream;
          ?62?????int?ret,flush;
          ?63?????char?in[4096];//存放輸入的數據
          ?64?????char?send[4096+18];//存放壓縮過后的數據
          ?65?????unsigned?int?have;
          ?66?????int?tmp;
          ?67?????memcpy(send,gzip_header,10);
          ?68?????memset(in,0,len);
          ?69?????stream.zalloc=Z_NULL;
          ?70?????stream.zfree=Z_NULL;
          ?71?????stream.opaque=Z_NULL;
          ?72?????stream.avail_in=0;
          ?73?????stream.next_in=Z_NULL;
          ?74?????memcpy(in,msg,len);
          ?75?????//壓縮初始化
          ?76?????tmp=deflateInit2(&stream,
          ?77?????????????Z_DEFAULT_COMPRESSION,//壓縮級別,從0-9
          ?78?????????????Z_DEFLATED,//壓縮方式
          ?79?????????????-MAX_WBITS,
          ?80?????????????8,
          ?81?????????????Z_DEFAULT_STRATEGY);
          ?82?????if(Z_OK!=tmp)
          ?83?????{
          ?84?????????perror("deflateInit2?Error");
          ?85?????????return?0;
          ?86?????}
          ?87?????stream.avail_in?=?len;?//要壓縮數據的長度
          ?88?????stream.next_in?=?in;????//要壓縮數據的首地址
          ?89?????stream.avail_out?=?4096;??//可存放的最大輸出結果的長多。就是壓縮后數據的最大長度
          ?90?????stream.next_out?=?send?+?10;?//存放壓縮數據的開始位置,send前十個字節用來放頭部
          ?91?????ret?=?deflate?(&stream,Z_FINISH);?//壓縮
          ?92?????switch(ret)
          ?93?????{
          ?94?????????case?Z_NEED_DICT:
          ?95?????????????ret=Z_DATA_ERROR;
          ?96?????????case?Z_DATA_ERROR:
          ?97?????????case?Z_MEM_ERROR:
          ?98?????????????(void)inflateEnd(&stream);
          ?99?????????????return?ret;
          100?????}
          101?????have?=?4096?-?stream.avail_out;
          102?????unsigned?crc?=?crc32(0L,?in,?len);
          103?????char?*?tail?=?send?+?10?+?have;
          104?????put_long?(tail,?crc);
          105?????put_long?(tail?+?4,?len);
          106?????write?(clifd,?send,?have?+?18);
          107?????deflateEnd?(&stream);
          108?????return?1;
          109?}
          110?
          111?void?app_exit()
          112?{
          113?????signal(SIGINT,SIG_DFL);
          114?????close(sockfd);
          115?????exit(0);
          116?}
          117?
          118?/*
          119??*?發送一個HTTP頭
          120??*?*/
          121?void?send_http_head(int?clifd)
          122?{
          123?????char?buf[4096];
          124?????memset(buf,0,sizeof(buf));
          125?????sprintf(buf,"HTTP/1.1?200?OK\r\n");
          126?????sprintf(buf,"%sServer:wunaozai.cnblogs.com\r\n",buf);
          127?????sprintf(buf,"%sContent-Encoding:?gzip\r\n",buf);//告訴瀏覽器,我接下來發送的數據是經過gzip壓縮過的
          128?????sprintf(buf,"%sContent-Type:?text/html\r\n\r\n",buf);
          129?????write(clifd,buf,strlen(buf));
          130?}
          131?
          132?/*
          133??*?開啟服務器監聽
          134??*?port:服務器端口
          135??*?成功返回套接字標識
          136??*?*/
          137?int?socket_listen(u_short?port)
          138?{
          139?????struct?sockaddr_in?sin;
          140?????int?on;
          141?????int?httpd=socket(PF_INET,SOCK_STREAM,0);
          142?????if(httpd==-1)
          143?????????perror("Fail?to?Socket");
          144?????//init?sockaddr_in
          145?????sin.sin_family=AF_INET;
          146?????sin.sin_port=htons(port);
          147?????sin.sin_addr.s_addr=htonl(INADDR_ANY);
          148?????bzero(&(sin.sin_zero),8);
          149?????setsockopt(httpd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
          150?????if(bind(httpd,(struct?sockaddr?*)&sin,sizeof(struct?sockaddr))==-1)
          151?????????perror("Fail?to?bind");
          152?????//如果port指定為零那么就隨機打開一個端口
          153?????if(port==0)
          154?????{
          155?????????socklen_t?len=sizeof(sin);
          156?????????if(getsockname(httpd,(struct?sockaddr?*)&sin,&len)==-1)
          157?????????????perror("Fail?to?getsockname");
          158?????????port=ntohs(sin.sin_port);
          159?????}
          160?????if(listen(httpd,100)<0)
          161?????????perror("Fail?to?listen");
          162?????printf("打開端口:%u\n",port);
          163?????return?httpd;
          164?}

          ?

            參考資料:?http://blog.csdn.net/reage11/article/details/8517631

                :?http://www.cppblog.com/Streamlet/archive/2010/09/22/127368.aspx

                :?http://blog.csdn.net/htttw/article/details/7616124

                :?http://www.cppblog.com/woaidongmao/archive/2009/09/07/95495.html

                :?http://blog.csdn.net/zhoudaxia/article/details/8039519

          ??????????????????????? :http://www.cnblogs.com/wunaozai/p/3960494.html


          posted on 2017-04-11 16:30 聽風 閱讀(767) 評論(0)  編輯  收藏 所屬分類: C++

          主站蜘蛛池模板: 广南县| 秦皇岛市| 神木县| 宝山区| 丁青县| 临清市| 宁海县| 金堂县| 罗城| 五大连池市| 海淀区| 临湘市| 黄平县| 曲周县| 大田县| 调兵山市| 晋江市| 内乡县| 文登市| 庄河市| 孙吴县| 桓仁| 沾益县| 章丘市| 廊坊市| 千阳县| 镇江市| 盈江县| 临安市| 皋兰县| 建昌县| 高台县| 抚州市| 深水埗区| 新丰县| 满城县| 开原市| 即墨市| 威海市| 台山市| 沅江市|