c - 在 C 程序中从 Web 服务器接收网页

标签 c buffer

这是我从服务器(实际上是 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 个字符的数组,但我认为这不是常规方式。

谢谢。

最佳答案

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

ssize_t nread;

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

if (nread < 0)
    perror("recv");

关于c - 在 C 程序中从 Web 服务器接收网页,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18607400/

相关文章:

c - 在 btrlib 上使用 qsort()/qsort_r() 不起作用

python ,C : redirected stdout fires [Errno 9]

c++ - 为什么派生类没有vtable指针而是使用基类的vtable?

c - fgets() 在 fscanf() 之后不起作用

c - 如何在 C 中初始化一个相当复杂的 char 数组?

gcc - 在 Ubuntu 11.04 中禁用堆栈崩溃保护

opengl-es - 在 OpenGL ES 中指定清晰颜色的目的是什么?

c++ - 如果整数溢出, (unsigned int) * (int) 的结果是什么?无符号或整数?

c++ - 如何编写高效的字符串缓冲区

c++ - ReadProcessMemory 的缓冲区应该是什么数据类型?