【问题标题】:Receiving data over HTTP - Inconsistent size通过 HTTP 接收数据 - 大小不一致
【发布时间】:2014-04-29 12:31:32
【问题描述】:
memset(buf, 0, sizeof(buf));
    int htmlstart = 0;
    char * htmlcontent;
    char *mainpage = (char *) malloc(MAXBUF);
    while((tmpres = recv(sock, buf, MAXBUF, 0)) > 0)
    {
        if(htmlstart == 0) //on first run, ignore headers
        {
            htmlcontent = strstr(buf, "\r\n\r\n");
            if(htmlcontent != NULL)
            {
                htmlstart = 1;
                htmlcontent += 4;
            }
        }
        else
        {
            htmlcontent = buf;
        }
        if(htmlstart)
        {
            mainpage = (char *) realloc( mainpage, (strlen(mainpage) + strlen(htmlcontent) + 1) );
            // printf("%s",htmlcontent);
            strcat(mainpage,htmlcontent);
        }
        memset(buf, 0, tmpres);
    }
    if(tmpres < 0)
    {
        perror("Error receiving data");
    }

    printf("%d",(int)strlen(mainpage));

我编写了一个简单的程序,在与服务器建立连接后通过 HTTP 接收数据。但是如果我尝试接收像图像这样的大对象,我会遇到一个奇怪的问题。每次我运行程序时,最后一个打印 HTTP 数据总大小(不包括标题)的打印语句都会有所不同。所以我收到的是损坏的图像/图像的一部分。

对为什么会发生这种情况有任何想法吗?

编辑:如果我在与mainpage 连接之前检查htmlcontent 的累积大小,即使在整个收据之后大小与mainpage 相同。所以问题不可能出在strcat 或任何其他字符串函数中。

【问题讨论】:

  • buf 不是字符串(它嵌入了零字节);你不能对它应用str* 函数。
  • 我实际上已经将它声明为一个字符串,因为我这样做主要是为了解析 HTML 数据,我只是不明白为什么它拒绝为图像工作。我知道将图像二进制数据存储在 char * 中很奇怪,但我看不出为什么它每次都不应该在完全相同的查询上接收相同大小的数据!
  • @user1265125 那你就不明白TCP和HTTP的关系了。您以某种方式期望 TCP recv 函数为您执行 HTTP 协议逻辑。它不能那样做。你必须这样做。
  • 其他人是正确的,因为您没有正确实现 HTTP 协议,并且您在应用 strxxx() 函数时不服从结果是二进制的。尽管如此,你的问题——据我所知——是为什么每次通话都会得到不同的结果/长度。这是因为您 strcat 到了一个未初始化的缓冲区(主页)。因为它可能会在随机位置有 NUL 字节,所以 strlen() 也会得到随机结果。

标签: c http


【解决方案1】:

你忘记实现 HTTP 协议了! HTTP 协议指定您如何知道何时拥有整个对象,例如,使用 Content-Length 标头之类的东西。 必须实现协议。 recv 函数只知道它正在读取字节流。

另外,您对strlenstrcat 的使用不正确。 recv 函数告诉你它收到了多少字节。 strlen 函数仅适用于字符串,而不适用于您尚未解析或处理的任意数据块。

【讨论】:

  • 不,我只是没有包含 HTTP 部分。当然,我创建并发送了标题。那就是尺寸较小的html页面没有问题。当我收到像图片这样大的东西时,问题就来了。
  • 您必须必须实现实际的 HTTP 协议。您的代码根本无法做到这一点!阅读 RFC 2616,它定义了 HTTP 协议。特别是,Section 4.4 解释了在接收响应的正文数据时如何知道何时阅读如何阅读以及阅读多少 .例如,看看我不久前发布的以下伪代码:stackoverflow.com/questions/7232931/…
  • @user1265125 是的,它在某些时候是靠运气工作的,而在其他时候却失败了,因为您实际上还没有实现 HTTP 协议,还因为您正在处理任意二进制数据,就好像它是字符串。你的代码在 HTTP 协议说应该之前就停止了,因为......它实际上并没有实现协议。
【解决方案2】:

如果您将strcat() 的某些内容传递给undefined buffer (mainpage)strlen() 将返回任意结果。

【讨论】:

    猜你喜欢
    • 2018-08-03
    • 2016-10-25
    • 1970-01-01
    • 1970-01-01
    • 2016-01-31
    • 1970-01-01
    • 2011-07-17
    • 1970-01-01
    • 2017-11-19
    相关资源
    最近更新 更多