2012-01-21 5 views
0

こんにちは、私はyahoo.comにリクエストを送信し、サーバが200 Okを返信し、エンコードされたgzipファイルを送る-transfer:チャンク。それはまあまあですが、私のプログラムを実行して、recv()を続けて呼び出すと、結局バスエラーが発生します。私はこの時点で何を意味するのか分かりません。また、パケットのヘッダーを読み取って、圧縮ファイルがマシンコードに入ってから送信されるバイト数を教えてもらう方法が不明です。この質問では、私のコードだけでなく、端末に表示される出力も含めて説明しました。recv()を呼び出した後のバスエラー/チャンクされた圧縮データを受け取る方法

#include <stdio.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netdb.h> 
#include <arpa/inet.h> 

#define MAXDATASIZE 500; 

int main(int argc, char *argv[]){ 
struct addrinfo serverSide,*serverInfo; 
int mySock, status; 
char buf[501],ipstr[INET6_ADDRSTRLEN]; 

memset(&serverSide, 0, sizeof serverSide); 
serverSide.ai_family = AF_UNSPEC; 
serverSide.ai_socktype = SOCK_STREAM; 

if(getaddrinfo("www.yahoo.com","80",&serverSide,&serverInfo)==0){ 

} 

mySock = socket(serverInfo->ai_family, serverInfo->ai_socktype, serverInfo->ai_protocol); 
connect(mySock, serverInfo->ai_addr, serverInfo->ai_addrlen); 

char msg[500] = "GET http://www.yahoo.com HTTP/1.1\r\n"; 
strcat(msg,"Host: www.yahoo.com:80\r\n"); 
strcat(msg,"User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:7.0.1) Gecko/20100101 Firefox/7.0.1\r\n"); 
strcat(msg,"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"); 
strcat(msg,"Accept-Language: en-us,en;q=0.5\r\n"); 
strcat(msg,"Accept-Encoding: gzip, deflate\r\n"); 
strcat(msg,"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"); 
strcat(msg,"Connection: keep-alive\r\n\r\n"); 

// I want to keep the code simple so I just call recv enough times to see what has been 
// written to my buffer. If I could read the packet length in the header then I would 
// code in a while loop to adjust for that. 
if((status = send(mySock,msg,strlen(msg),0))== -1){ 
printf("request not sent %d\n",status); 
perror("\n"); 
}else{ 
if((status = recv(mySock, buf, 1500, 0))== -1){ 
printf("recieved byte error"); 
}else{ 
printf("%s",buf); 
} 
if((status = recv(mySock, buf, 1500, 0))== -1){ 
printf("recieved byte error"); 
}else{ 
printf("%s",buf); 
} 
if((status = recv(mySock, buf, 1500, 0))== -1){ 
printf("recieved byte error"); 
}else{ 
printf("%s",buf); 
} 
if((status = recv(mySock, buf, 1500, 0))== -1){ 
printf("recieved byte error"); 
}else{ 
printf("%s",buf); 
} 
} 
close(mySock); 
freeaddrinfo(serverInfo); 
return 0; 
} 

ベローは私のコードの出力です。土、2012年1月21日午前八時53分09秒GMTのSet-Cookie:サーバーは...以下に

HTTP/1.1 200 OK応答日 B = 4peq6lh7hkv7l & B = 3つの& S = U4を。 expires = Tue、20-Jan-2014 20:00:00 GMT; パス= /; domain = .yahoo.com P3P: policyref = "http://info.yahoo.com/w3c/p3p.xml"、CP = "CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELO OTPi OUR DELI SAMIキャッシュ制御:プライベートXフレームオプション:SAMEORIGINセットクッキー: IU =削除;キャッシュ制御:プライベートXフレームオプション:SAMEORIGINセットクッキー: IU =削除; expires = Fri、21-Jan-2011 08:53:09 GMT;パス= /; ドメイン= .yahoo.comセットクッキー:PH =削除済み。有効期限= 2011年1月21日(金) 08:53:09 GMT;パス= /;ドメイン= .yahoo.com-クッキー設定します。 FPC = D = 2BrdHmSMUw00.1uwnK1w8hHJcKnQt3UjRGxvUnBVIn0e6eAyRyd96eAPIN33Jne3IWoEE8r8eAk9xF0ExLsN5JJJmANZRlEBg8hpcDJ1GD7Gd50uZeP1H0_Wbf_mc.LJ45tDfhhwjR1BSedjT7AeGszK321i_gS34xKNuHlH2niKnP1lFG8y3aztEQsOkQHUu1w3zxk- & V = 2; 期限切れ= Sun、2013年1月20日08:53:10 GMT;パス= /; domain = www.yahoo.com Set-Cookie:CH =削除済み。 expires = Fri、21-Jan-2011 08:53:09 GMT;パス= /; ドメイン= www.yahoo.comセットクッキー: CH = AgBPGnwQAA9AEAAA3RAAKY0QAAMPEAAYcxAAKN0QAD5XEAASNBAAJeoQACI8; 期限切れ= 2012年2月20日(月)08:53:09 GMT;パス= /;ドメイン= .yahoo.com のSet-Cookie: FPT = D = nZFZlZHXecyEB3UWO0p6uOQtHkIdLjY734kqWOMHwg8Yq1e0sUpJBiMgYN63uaJ0.zEBsZIbeO93bfF0mXfQ8CtJYxAuet8CIS5PYmNMWfBDUU6ew8pXSI6cY3aX7Nk743wzRxbuCoBZGqvOM0eGhQMFOQ7BrCYBAZsAIYAOqwHKu7sNvbkPN7r0T7ncKpu5bX8LWPGngHHS97cCbNgpbgzOh13nP1m6.9cw7oPeudXdRjfzxsDUYqq2LvQJdECPWmccPhDEYfAoIl.Cfc8T8w_5.zrvoWG5kJr_T0megV4GtcTB324ZS2zkf0pi1GiMGYVHxGNh01c04XJnjk5q0ek_Xgogaa5oZoyhkMYQLI66nMCt1yAiz1jXmq2MTBxHqtbxBkoJaVsJt0YQMdpkkxwpRpXZHUgur.K9kY4j3vgyG1j44CQPlNsh7mBMxNe5nLdCMjFMy0ufmocRYowg38kMiK9hpFqkFnwYZSZPMGM4wAK5wVvFrwn1phkY3OXr76z5OC5tjNeq3Q-- & V = 1; パス= /;ドメイン= www.yahoo.com Set-Cookie:fpps = deleted; expires = Fri、 21-Jan-2011 08:53:09 GMT;パス= /;ドメイン= www.yahoo.comのSet-Cookie: fpc_s = D = 33OMFTGMUw2Z.oeMhzS8DGMizJ2NFSc4VT5QjW6pM.25xOqOYy5nr_kK5C83.tjkxzIiFvBITPc7P5YBehviyRS3piAAliJxvHQHDlbZYOlAdvgPXzJ4zGghf.xEL6Rb6rVdP90xlOc_njpBqlqOcwyMeq0ZqBy2VXuNrIxiD9QjUUsJyfVJ4miF1frSXQOI5Z8MVIErFoBjW3jTQANFu_CayJrjp6RRDc.YG5DCn04SFk3hKALdzVPSyIoawxmicCoWFfN7dvyge8jRoeQXHey.IALpAtcCPlY4eX.teLb.GO0yQxUN5HzgR9I- & V = 2; パス= /;コンテンツタイプ: text/html; charset = utf-8コンテンツエンコーディング:gzip年齢:2 転送エンコーディング:チャンク接続:キープアライブサーバー:YTS/1.20 。0

000088e IHG8Ae ��t�>#%xc�c#���a��e9��*d��S��@�~}�ZF��~x� 6�S8�#ӉO�i:i%��?���a��9rxJ�n���<Q����_�-�A����!D{�{ޱN���f*/h��ΰ ���Ea�h��E��2UY� 2�7�����dL>U���^W˳g��H�Q�>���~����iiΟ��@:���R�L�b��K���=�# Ғ�5���|'�J��eo {バスエラー

答えて

2
char buf[501]; 
... 
recv(mySock, buf, 1500, 0) 
        ^^^^ 

recvがこれまで実際に超える501のバイトを読み込む場合は、未定義の動作になり、あなたのバッファを、オーバーフローます。 501バイト以上のデータを読まないようにするか、バッファのサイズを増やしてください。

printfも安全ではありません。入力が適切であることを保証するものはありません。0 - 終端されたC文字列。 (あなたは長さrecvが返さwriteを使用して渡すことができます。)

+0

しかし、今はもうエラーが出ません。これらのパケットの開始と終了を知りたい場合は、gzipのチャンクをどのように読みますか? –

+1

これはTCPです。パケットの開始/終了はなく、ストリームだけです。ヘッダーを解析し、チャンクされたエンコードを解析して、どれだけ読む必要があるかを把握する必要があります。 – Mat

+0

RFC 2616セクション3.6.1を読んでください。 'チャンクされた'転送がどのように動作するかを正確に説明しています。各チャンクは、チャンク内に残っているバイト数を指定するテキスト行から始まり、バイトの後にCRLF改行が続きます。最後のチャンクのバイトサイズは0です。追加の一連のHTTPヘッダーが応答を完了します。 –

1

を一目で、あなたはbufをオーバーランしているように見えます。長さが501であると宣言してから、1500バイトを読み込みます。

+0

ああ、私はそれをキャッチしませんでした。ありがとう、私は実際には3つの異なるファイルを持っており、私は501から1500まですべてを変更したと思った。私のバッファーがあふれているように見えましたが、どうしたらいいかわかりませんでした。あなたの修正は働いた!再度、感謝します! –

関連する問題