首页 > 解决方案 > 调用 recv() 函数时接收多个 html 内容?

问题描述

我正在编写一个 http 客户端来从网站接收 html。

这是代码:我只是添加了一段包含与套接字相关的逻辑的代码,因此缺少字符串(char [])和函数的初始化

scanf("%s",&URL);
int c_socket = socket(AF_INET, SOCK_STREAM, 0);

struct sockaddr_in urladdress;
urladdress.sin_family = AF_INET;
urladdress.sin_port = htons(PORT);
urladdress.sin_addr.s_addr = inet_addr(URL);

connect(c_socket, (struct sockaddr*) &urladdress, sizeof(urladdress));

char REQUEST[] = "GET / HTTP/1.1\r\n\r\n";
char response[512];
int size_recv,total_recv = 0;
std::string content = " ";
send(c_socket, REQUEST, sizeof(REQUEST), 0);

while((size_recv = recv(c_socket, response, sizeof(response), 0)) > 0 && content[content.length()]!='\n')
{
    content += response;
    memset(response ,0 , sizeof(response));
}
close(c_socket);
printf("%s",content.c_str());

在接收 html 时,我得到多个 html 内容,在 html 代码完成后,我再次得到相同 html 的某些部分,而且大部分都不完整,似乎服务器正在发送多个文件。

像这样的东西:

<!-- header -->
<html> something </html>
<!-- header -->
<html> someth

我认为这是由于连续调用recv()函数来获取所需的所有数据。如您所见,我已经在 while 循环中设置了条件,以便在到达结束时自动停止接收数据,但它没有停止。

我不知道这是否是预期的,我必须设置一些其他逻辑来阻止更多调用recv(),如果是,那么是什么逻辑。是不是我必须写一些东西来格式化数据,以便它只包含一个 html 正文,比如在</html>找到标签后删除所有内容。

到目前为止,我发现的所有帖子都解释说,预计不会一次收到所有数据,所以我不得不多次调用recv()。但他们似乎没有说接收多个 html 正文并写一些停止的逻辑。

标签: csocketsget

解决方案


TCP 是基于流的协议,这意味着单次读取可以对应多条消息或部分消息。

您需要阅读 Content-Length 标头以了解您应该读取多少字节。如果您碰巧获得了比您要求的更多字节,则需要缓冲这些字节并将它们保存以供您阅读下一条消息。


推荐阅读