2012-01-21 1 views
0

Привет, У меня есть простой браузер, который отправляет запрос на yahoo.com, который отвечает на сервер, сообщив мне 200 Ok и что он отправит мне gzip-файл, используя закодированный -перечисление: фрагментированное. Thats штраф и все, но когда я запускаю свою программу и постоянно вызываю 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; 
} 

Bellow - это выход моего кода. Сервер отвечает следующим ...

HTTP/1.1 200 OK Date: Sat, 21 Jan 2012 8:53:09 GMT Set-Cookie: B = 4peq6lh7hkv7l & Ь = 3 & S = U4; expires = Tue, 21-Jan-2014 20:00:00 GMT; path = /; 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 НАШИ DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE LOC GOV " Cache-Control: частные X-Frame-Options: SAMEORIGIN Set-Cookie: IU = deleted; expires = Fri, 21-Jan-2011 08:53:09 GMT; Путь = /; домен = .yahoo.com Set-Cookie: PH = удален; expires = Fri, 21-Jan-2011 08:53:09 GMT; Путь = /; домен = .yahoo.com Set-Cookie: FPC = d = 2BrdHmSMUw00.1uwnK1w8hHJcKnQt3UjRGxvUnBVIn0e6eAyRyd96eAPIN33Jne3IWoEE8r8eAk9xF0ExLsN5JJJmANZRlEBg8hpcDJ1GD7Gd50uZeP1H0_Wbf_mc.LJ45tDfhhwjR1BSedjT7AeGszK321i_gS34xKNuHlH2niKnP1lFG8y3aztEQsOkQHUu1w3zxk- & v = 2; expires = Sun, 20-Jan-2013 08:53:10 GMT; Путь = /; domain = www.yahoo.com Set-Cookie: CH = удалено; expires = Fri, 21-Jan-2011 08:53:09 GMT; Путь = /; domain = www.yahoo.com Set-Cookie: CH = AgBPGnwQAA9AEAAA3RAAKY0QAAMPEAAYcxAAKN0QAD5XEAASNBAAJeoQACI8; expires = Пн, 20-фев-2012 08:53:09 GMT; Путь = /; домен = .yahoo.com Set-Cookie: FPT = d = nZFZlZHXecyEB3UWO0p6uOQtHkIdLjY734kqWOMHwg8Yq1e0sUpJBiMgYN63uaJ0.zEBsZIbeO93bfF0mXfQ8CtJYxAuet8CIS5PYmNMWfBDUU6ew8pXSI6cY3aX7Nk743wzRxbuCoBZGqvOM0eGhQMFOQ7BrCYBAZsAIYAOqwHKu7sNvbkPN7r0T7ncKpu5bX8LWPGngHHS97cCbNgpbgzOh13nP1m6.9cw7oPeudXdRjfzxsDUYqq2LvQJdECPWmccPhDEYfAoIl.Cfc8T8w_5.zrvoWG5kJr_T0megV4GtcTB324ZS2zkf0pi1GiMGYVHxGNh01c04XJnjk5q0ek_Xgogaa5oZoyhkMYQLI66nMCt1yAiz1jXmq2MTBxHqtbxBkoJaVsJt0YQMdpkkxwpRpXZHUgur.K9kY4j3vgyG1j44CQPlNsh7mBMxNe5nLdCMjFMy0ufmocRYowg38kMiK9hpFqkFnwYZSZPMGM4wAK5wVvFrwn1phkY3OXr76z5OC5tjNeq3Q-- & v = 1; path = /; domain = www.yahoo.com Set-Cookie: fpps = deleted; expires = Fri, 21-янв-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; path = /; domain = www.yahoo.com Vary: Accept-Encoding Content-Type: text/html; charset = utf-8 Content-Encoding: gzip Возраст: 2 Передача-кодирование: chunked Подключение: keep-alive Сервер: 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 {Bus

ответ

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

Если recv когда-либо на самом деле читает более 501 байт, вы переполнить ваш буфер, что приводит к непредсказуемому поведению , Убедитесь, что вы никогда не читаете больше 501 байт или увеличиваете размер вашего буфера.

Также небезопасны printf. Нет ничего, что гарантировало бы правильность ввода, 0 -строчные строки C. (Вы можете использовать write и передать длину recv.)

+0

Но теперь, когда я больше не получаю эту ошибку, как мне читать куски для gzip, если я хочу знать начало и конец этих пакетов? –

+1

Это TCP, нет старта/конца пакетов, просто поток. Вам нужно будет разобрать заголовки и самостоятельно разобрать кодировку, чтобы выяснить, сколько вам нужно читать. – Mat

+0

Прочтите RFC 2616 Раздел 3.6.1. В нем точно объясняется, как работают «chunked». Каждый фрагмент начинается с строки текста, которая указывает, сколько оставшихся байтов находится в куске, а затем за байтами следует разрыв строки CRLF. Последний кусок имеет размер байта 0, а затем набор дополнительных HTTP-заголовков завершает ответ. –

1

С первого взгляда, похоже, что вы обгоняете buf; вы объявляете его как имеющее длину 501, но затем попытайтесь прочитать в нем 1500 байт.

+0

О, вау, я этого не понимал. Спасибо, у меня на самом деле есть три разных файла, и я подумал, что я изменил все с 501 до 1500. Казалось, что я переполнял свой буфер, но я не знал, как это сделать. Ваше исправление работает! Еще раз спасибо! –

 Смежные вопросы

  • Нет связанных вопросов^_^