gzipで圧縮されたhttpレスポンスの問題はほとんどありません。ヘッダーからデータ部分を区切りましたが、gzipヘッダーとメッセージに\ 0文字が含まれています。 gzippedチャンク?C - 圧縮解除されたHTTPレスポンス
strcat、strlenのような文字列関数は、チャンク内のさまざまな場所で¥0文字を含む圧縮されたgzippedデータであるため使用できません。
私はlibcurlを使用しましたが、Cソケットよりも比較的低速です。ここ
は、サンプル応答の一部である:
HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Type: text/html; charset=utf-8
P3P: CP="NON UNI COM NAV STA LOC CURa DEVa PSAa PSDa OUR IND"
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 12605
Date: Mon, 05 Mar 2012 11:46:30 GMT
Connection: keep-alive
Set-Cookie: _FP=EM=1; expires=Wed, 05-Mar-2014 11:46:29 GMT; domain=.bing.com; path=/
����ՠ����AU��o�
サンプルコード:
#define MAXDATASIZE 1024
char *recvData; // Holds entire gzip data
char recvBuff[MAXDATASIZE]; // Holds gzip chunk
int offset=0;
while(1){
recvBytes = recv(sockfd, &recvBuff, MAXDATASIZE-1, 0);
totalRecvBytes += recvBytes;
// get content length, this runs first time only as required
if(!clfnd){
regi = regexec(&clregex, &recvBuff, 3, clmatch, 0);
if(!regi){
strncpy(clarr, recvBuff + clmatch[2].rm_so, clmatch[2].rm_eo-clmatch[2].rm_so);
clarr[clmatch[2].rm_eo-clmatch[2].rm_so] = '\0';
cl = atoi(clarr);
clfnd=1;
regfree(&clregex);
recvData = malloc(cl * sizeof(char));
memset(recvData, 0, sizeof recvData);
}
}
// get data part from 1st iteration, furthur iterations contain only data
if(!datasplit){
int strtidx;
char *datastrt = strstr(&recvBuff, "\r\n\r\n");
if(datastrt != NULL){
strtidx = datastrt - recvBuff + 4;
memcpy(recvData, recvBuff + strtidx, recvBytes-strtidx);
datasplit=1;
offset = recvBytes-strtidx;
}
}
else{
memcpy(recvData + offset, recvBuff, recvBytes);
offset += recvBytes;
}
if (offset >= cl)
break;
}
char *outData = malloc(offset*4 * sizeof(char));
memset(outData, 0, sizeof outData);
int ret = inf(recvData, offset, outData, offset*4);
機能を膨らま:
int inf(const char *src, int srcLen, const char *dst, int dstLen){
z_stream strm;
strm.zalloc=NULL;
strm.zfree=NULL;
strm.opaque=NULL;
strm.avail_in = srcLen;
strm.avail_out = dstLen;
strm.next_in = (Bytef *)src;
strm.next_out = (Bytef *)dst;
int err=-1, ret=-1;
err = inflateInit2(&strm, MAX_WBITS+16);
if (err == Z_OK){
err = inflate(&strm, Z_FINISH);
if (err == Z_STREAM_END){
ret = strm.total_out;
}
else{
inflateEnd(&strm);
return err;
}
}
else{
inflateEnd(&strm);
return err;
}
inflateEnd(&strm);
printf("%s\n", dst);
return err;
}
あなたはいくつかの大きな問題を抱えています...受け取ったパケットごとにrecvDataを割り当ててクリアします.1)あなたがメモリをリークさせ、2)最後のrecvDataに0の束と最後のパケットが含まれていることを意味します。また、私はオフセットのあなたの使用がファンキーであると思う、それは最初のパケットのために更新されていません。 – harald
おっと... 1)プログラムはrecvDataに1回だけメモリを割り当てます。基本的にはコードをコピーしていますので、問題はありませんので、その状態をコピーするのを忘れました。更新されたコードを参照してください2)オフセットは一時的に3に設定され、 memcpy()の最初のmemcpy()はそれを必要としません。2 memcpy()を書く理由は、最初のmemcpy()のIF条件でデータからヘッダを分割して、オフセットをヘッダを除いたデータバイト数バイトすなわちオフセット= recvBytes-strtidx;問題は最初のmemcpy()で\ 0文字をコピーしていないことです。recvBuffのgzippedデータから3文字しかコピーしません。 – Coder
プログラムはhttp応答を解凍します! memcpy()は\ 0文字をコピーしていましたが、Eclipseデバッガはgzipチャンク全体を表示していなかったため、\ 0で破損していました。上記のコードを更新しました。 – Coder