こんにちは、私は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
{バスエラー
しかし、今はもうエラーが出ません。これらのパケットの開始と終了を知りたい場合は、gzipのチャンクをどのように読みますか? –
これはTCPです。パケットの開始/終了はなく、ストリームだけです。ヘッダーを解析し、チャンクされたエンコードを解析して、どれだけ読む必要があるかを把握する必要があります。 – Mat
RFC 2616セクション3.6.1を読んでください。 'チャンクされた'転送がどのように動作するかを正確に説明しています。各チャンクは、チャンク内に残っているバイト数を指定するテキスト行から始まり、バイトの後にCRLF改行が続きます。最後のチャンクのバイトサイズは0です。追加の一連のHTTPヘッダーが応答を完了します。 –