2011-12-06 29 views
1

如果我telnet到telnet www.xlhi.com 80,并应用以下GET请求:从C scoket:的recv(...)没有返回正确的字节

GET http://www.xlhi.com/ HTTP/1.1 
Host: www.xlhi.com 
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:7.0.1) Gecko/20100101 Firefox/7.0.1 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: en-us,en;q=0.5 
Accept-Encoding: gzip, deflate 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 
Proxy-Connection: keep-alive 
Cookie: CG=IE:04:Cork 
Cache-Control: max-age=0 

我得到如下回应:

HTTP/1.1 200 OK 
Date: Tue, 06 Dec 2011 10:35:08 GMT 
Server: Apache/2.2.14 (Ubuntu) 
X-Powered-By: PHP/5.3.2-1ubuntu4.9 
Vary: Accept-Encoding 
Content-Encoding: gzip 
Content-Length: 48 
Content-Type: text/html 

��(�ͱ���I�O����H�����ч�� 
          �4�@� 

一切如预期的那样很好。我对返回的gzipped二进制数据感兴趣(“Hello”)。

现在,我有一个适用于GET请求到服务器(在这种情况下www.xlhi.com)

char* applyGetReq(char* url,char* data,int len){ 
     int sockfd, numbytes; 
     struct addrinfo hints, *servinfo, *p; 
     int rv; 
     char s[INET6_ADDRSTRLEN]; 

     memset(&hints, 0, sizeof hints); 
     hints.ai_family = AF_UNSPEC; 
     hints.ai_socktype = SOCK_STREAM; 
     printf("Server name: %s\n\n",url); 
     if ((rv = getaddrinfo(url,"80", &hints, &servinfo)) != 0) { 
       fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); 
       exit(1); 
     } 

     // loop through all the results and connect to the first we can 
     for(p = servinfo; p != NULL; p = p->ai_next) { 
       if ((sockfd = socket(p->ai_family, p->ai_socktype,p->ai_protocol)) == -1) { 
         perror("client: socket"); 
         continue; 
       } 
       if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) { 
         close(sockfd); 
         perror("client: connect"); 
         continue; 
       } 
       break; 
     } 

     if (p == NULL) { 
       fprintf(stderr, "client: failed to connect\n"); 
       exit(1); 
     } 

     inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),s, sizeof s); 
     //printf("client: connecting to %s\n", s); 

     sendall(sockfd,data,&len); 

     freeaddrinfo(servinfo); // all done with this structure 

     char* buf=malloc(MAXDATASIZE*sizeof(char)); 
     if ((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) { 
       perror("recv"); 
       exit(1); 
     } 
     //printf("numbytes:%d\n",numbytes); 
     buf[numbytes] = '\0'; 
     close(sockfd); 
     return buf; 
} 

现在这个C函数,当我调用该函数并打印出结果:

... 
    int len = strlen(data); //data is a char[] and contains the exact same GET request as mentioned above 
    char* buf=NULL; 
    buf=applyGetReq(stripped_url,data,len); 
    printf("%s\n",buf); 

我从服务器得到如下回应:

HTTP/1.1 200 OK 
Date: Tue, 06 Dec 2011 10:03:13 GMT 
Server: Apache/2.2.14 (Ubuntu) 
X-Powered-By: PHP/5.3.2-1ubuntu4.9 
Vary: Accept-Encoding 
Content-Encoding: gzip 
Content-Length: 48 
Content-Type: text/html 

� 

正如你可以看到,页面内容(二进制数据)因某种不明原因而被缩短。我应该得到:

��(�ͱ���I�O����H�����ч�� 
           �4�@� 

我一直在看这两个小时现在似乎无法得到它的底部,所以我认为我会问社区。

+1

不在你的二进制数据中的所有字符是可以打印的,也许这就是为什么你会得到不同的输出的原因。你是否尝试在十六进制中打印二进制数据? – thumbmunkeys

回答

4

这就是printf的工作原理。它在遇到NUL(0)字节时停止。尝试使用其他功能

fwrite(buf, 1, numbytes, stdout); 
+0

谢谢。任何方式来输出缓冲区?请记住我对C很新... – Eamorr

+0

@Eamorr我用'fwrite'添加了一个例子。 – cnicutar

+0

嘿,谢谢你。我现在可以看到二进制数据。我现在必须从响应头中提取响应的长度。唷!我认为我的代码比现在糟糕得多。 – Eamorr