下面是我从服务器(实际上是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个字符的数组,但我认为这不是传统的方法。
谢谢。
发布于 2013-09-04 07:07:47
一个典型的解决方案是在循环中调用recv(2)并保持处理(打印?)接收字节。这样,您就可以接收任意大小的页面。
ssize_t nread;
while ((nread = recv(sockfd, page, sizeof page, 0)) > 0) {
/* .... */
}
if (nread < 0)
perror("recv");发布于 2013-09-04 07:16:52
您通常要做的是将数据存储在动态数组中,在C语言中,动态数组是使用realloc()来增长内存块的。
您通常使用像您这样的较小的静态分配数组来重复读取,然后一旦获得了新的字节块,就会将其附加到动态数组中,并在需要时进行扩展。
您必须跟踪动态数组的实际长度(存储在其中的下载字符数量)和分配的长度(可用于存储数据的字节数)。
发布于 2013-09-04 07:54:30
动态数组是处理“未知长度”问题的一种方法,当需要下载更多字节时,可以动态地放大数组。
我认为您可以首先解码HTTP响应头,如果报头有“内容长度”字段,那么您就知道HTTP响应消息的长度(响应主体包含请求的文档)。这样,您就可以为页面缓冲区分配足够的空间。
https://stackoverflow.com/questions/18607400
复制相似问题