调用recv()函数时接收多个html内容吗?

时间:2018-10-24 15:38:55

标签: c sockets get

我正在编写一个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正文,并编写了一些停止逻辑。

1 个答案:

答案 0 :(得分:1)

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

您需要读取Content-Length标头才能知道应该读取多少字节。如果您碰巧得到了更多的字节,然后又提出了要求,则需要缓冲这些字节并将其保存,以备下一次阅读时使用。