1

这是我从服务器(实际上是 google.com)获取网页的代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>

char http[] = "GET / HTTP/1.1\nAccept: */*\nHost: www.google.com\nAccept-Charset: utf-8\nConnection: keep-alive\n\n";
char page[BUFSIZ];

int main(int argc, char **argv)
{
    struct addrinfo hint, *res, *res0;

    char *address = "www.google.com";
    char *port = "80";

    int ret, sockfd;

    memset(&hint, '\0', sizeof(struct addrinfo));

    hint.ai_family = AF_INET;
    hint.ai_socktype = SOCK_STREAM;
/*  hint.ai_protocol = IPPROTO_TCP; */

    if((ret = getaddrinfo(address, port, &hint, &res0)) < 0)
    {
        perror("getaddrinfo()");
        exit(EXIT_FAILURE);
    }

    for(res = res0; res; res = res->ai_next)
    {
        sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);

        if(-1 == sockfd)
        {
            perror("socket()");
            continue;
        }

        ret = connect(sockfd, res->ai_addr, res->ai_addrlen);

        if(-1 == ret)
        {
            perror("connect()");
            sockfd = -1;
            continue;
        }

        break;

    }

    if(-1 == sockfd)
    {
        printf("Can't connect to the server...");
        exit(EXIT_FAILURE);
    }

    send(sockfd, http, strlen(http), 0);

    recv(sockfd, page, 1023, 0);

    printf("%s\n", page);

    return 0;
}

我刚刚定义了一个“BUFSIZ”字符数组来存储网页。BUFSIZ 在我的操作系统上实际上是 1024 个字符,因此,我可以存储一个长度为 1024 个字符的网页。但是如果页面实际上大于 1024 怎么办?我的意思是,如何存储大于 1024 个字符的页面?我可以定义一个包含 2048、4096 甚至 10,000 个字符的数组,但我认为这不是常规方式。

谢谢。

4

3 回答 3

2

recv(2)一种典型的解决方案是循环调用并继续处理(打印?)接收到的字节。这样您就可以接收任何大小的页面。

ssize_t nread;

while ((nread = recv(sockfd, page, sizeof page, 0)) > 0) {
    /* .... */
}

if (nread < 0)
    perror("recv");
于 2013-09-04T07:07:47.113 回答
1

您通常所做的是将数据存储在一个动态数组中,在 C 中实现该数组是realloc()为了增加一块内存。

您通常使用像您这样的较小的静态分配数组来重复读取,然后一旦获得一个新的字节块,您就将它附加到动态数组中,如果需要,可以增长它。

您将不得不单独跟踪动态数组的实际长度(已下载的已存储在其中的字符数)和分配的长度(用于存储数据的字节数)。

于 2013-09-04T07:16:52.950 回答
0

动态数组是一种处理“未知长度”问题的方法,当需要下载更多字节时,您可以动态扩大数组。

我认为您可以先解码 HTTP 响应标头,如果标头具有“Content-Length”字段,则您知道 HTTP 响应消息的长度(响应正文包含请求的文档)。这样您就可以为页面缓冲区分配足够的空间。

于 2013-09-04T07:54:30.330 回答