1

我有这个简单的 C 代码,它尝试使用 80 端口连接到 www 主机。我收到的是正常的 http 标头响应,但我收到的不是 HTML 内容,而是未知字符(我在打印垃圾吗?)

(facebook.com 只是一个例子,它发生在任何服务器上)查看我的代码:

  #define BUF_SIZE 4096
  struct sockaddr_in sockaddr;
  struct hostent *host;

  char buffer[BUF_SIZE] = { 0 };
  int sock;

  static const char const headers[] =
    "GET / HTTP/1.1\r\n"
    "Host:www.facebook.com\r\n"
    "User-Agent:Mozilla/5.0 (X11; Linux i686; rv:7.0.1) Gecko/20100101 Firefox/7.0.1\r\n"
    "Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
    "Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
    "Accept-Encoding:gzip,deflate\r\n"
    "Connection:close\r\n"
    "\r\n\r\n";

  if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
    perror("Cannot create TCP socket");
    exit(1);
  }

  if((host = gethostbyname("www.facebook.com")) == NULL) {
    perror("Cannot get host");
    exit(1);
  }

  memset(&sockaddr, 0, sizeof(sockaddr));
  sockaddr.sin_family = AF_INET;
  memcpy(&sockaddr.sin_addr,
     host -> h_addr_list[0],
     (size_t) host -> h_length);
  sockaddr.sin_family = AF_INET;
  sockaddr.sin_port = htons(80);

  if(connect(sock, (struct sockaddr *)&sockaddr, sizeof(struct sockaddr)) == -1) {
    perror("cannot connect");
    exit(1);
  }

  if(send(sock, headers, strlen(headers), 0) == -1) {
    perror("Cannot send packet");
    exit(1);
  }

  ssize_t readed;
  while((readed = recv(sock, buffer, BUF_SIZE, 0)) > 0) {
    write(fileno(stdout), buffer, readed);
    memset(buffer, 0, readed);
  }

  close(sock);

响应示例:

HTTP/1.1 200 OK
Cache-Control: private, no-cache, no-store, must-revalidate
Expires: Sat, 01 Jan 2000 00:00:00 GMT
P3P: CP="Facebook does not have a P3P policy. Learn why here: http://fb.me/p3p"
Pragma: no-cache
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Set-Cookie: datr=7HVjUC3-OlTdOMH3HivA_8Ge; expires=Fri, 26-Sep-2014 21:38:52 GMT; path=/; domain=.facebook.com; httponly
Set-Cookie: reg_ext_ref=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/; domain=.facebook.com
Set-Cookie: reg_fb_gate=http%3A%2F%2Fwww.facebook.com%2F; path=/; domain=.facebook.com
Set-Cookie: reg_fb_ref=http%3A%2F%2Fwww.facebook.com%2F; path=/; domain=.facebook.com
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
X-FB-Debug: 36+IohXvxWRp+3LHt+aLebawuS3W/MaBkmgR9TJGMrk=
Date: Wed, 26 Sep 2012 21:38:52 GMT
Transfer-Encoding: chunked
Connection: close

2f03
�}Yo�X��{�
�S-U)���P!����V��2�
                  F�A�AFr       -9
                                        �
��0�p�{�1cx��1`▒������0m�                �
                         �\��XH)3U�v��yy���{��g�O��:�l_�lKoh�����L��7��'K�֐{jW����,uM�ue+��L�uU[:�=U�T�ս��{�LM���Oݮc����ou=ö$�▒;XR��G;K]�e;KcՑ4ɰ$u��Z{�P�c���[�6,;^u�w���������K��m��v����A���v!�pm�m�W���'�A�ծٹk��q���������Z�g�Ǘ�#�+���\��tU�������*s�V�ڶ7��W��[�����������xO��uM��jZ���ptR����Z5qv�QO��Ʀww���5K7�����Mg�c^쩻C+h��M<;V՛ڕ��e���P�1��գw���?���~w~�����ܖ�ky�U����X�����UTk\�Xw�'�b�V\����<Єҳ���ؖbڪ��z*�'%���⍬[od��]�H��W��?F��q� ��M�&lt;�n�Owl)�&gt;�fK�R~E�
                                                                                ��
[...]

如何解决这个问题?

4

2 回答 2

5

删除行:

"Accept-Encoding:gzip,deflate\r\n"

因为它告诉远程主机 yoz 接受压缩数据,而你不接受!

于 2012-09-26T21:46:19.787 回答
4

这很简单。您形成了一个请求,通知服务器您支持 gzip 传输编码。从您的请求中删除"Accept-Encoding:gzip,deflate\r\n" ,您将看到纯文本作为响应

于 2012-09-26T21:46:53.363 回答