C++ 破损的HTML-浏览器不';t从我的Web服务器下载整个HTTP响应,CURL则下载 症状

C++ 破损的HTML-浏览器不';t从我的Web服务器下载整个HTTP响应,CURL则下载 症状,c++,http,sockets,embeddedwebserver,C++,Http,Sockets,Embeddedwebserver,我想,我搞砸了,因为Mozilla Firefox和Google Chrome都产生了相同的错误:它们没有收到Web服务器发送给它们的全部响应。CURL从不遗漏,快速滚动响应的最后一行始终为“” 理由 原因是,我发送了更多部分的响应: sendHeaders(); // is calls sendResponse with a fix header sendResponse(html_opening_part); for ( ...scan some data... )

我想,我搞砸了,因为Mozilla Firefox和Google Chrome都产生了相同的错误:它们没有收到Web服务器发送给它们的全部响应。CURL从不遗漏,快速滚动响应的最后一行始终为“”

理由 原因是,我发送了更多部分的响应:

    sendHeaders();  // is calls sendResponse with a fix header
    sendResponse(html_opening_part);
    for ( ...scan some data... ) {
        sendResponse(the_data);
    } // for
    sendResponse(html_closing_part)
浏览器在sendResponse()调用之间停止接收数据。此外,Web服务器不会关闭()套接字,只是在最后关闭

(我这样做的原因:我编写的程序是为非linux系统设计的,它将在嵌入式计算机上运行。它没有太多内存,大部分内存都被lwIP堆栈占用。因此,避免收集相对巨大的网页,我将其分部分发送。像它这样的浏览器,在linux下不会出现损坏的HTML。)

环境 该平台是GNU/Linux(Ubuntu 32位,内核为3.0)。我的小型Web服务器以标准方式将内容发送回客户端:

    int sendResponse(char* data,int length) {

        int x = send(fd,data,length,MSG_NOSIGNAL);
        if (x == -1) {
            perror("this message never printed, so there's no error \n");
            if (errno == EPIPE) return 0;
            if (errno == ECONNRESET) return 0;

            ... panic() ... (never happened) ...

        } // if send()

    } // sendResponse()
这是我正在使用的固定标题:

    sendResponse(
        "HTTP/1.0 200 OK\n"
        "Server: MyTinyWebServer\n"
        "Content-Type: text/html; charset=UTF-8\n"
        "Cache-Control: no-store, no-cache\n"
        "Pragma: no-cache\n"
        "Connection: close\n"
        "\n"
    );
问题:
这正常吗?我必须用一个send()发送整个响应吗?(我现在正在研究,直到一个快速的解决方案到来。)

如果您阅读RFC2616,您将看到您应该使用
CR+LF
作为行尾

除此之外,打开浏览器开发人员工具,查看他们提出的确切请求。使用Netcat之类的工具复制请求,然后依次删除每个标头,直到它开始工作。

明白了

正如@Jim所建议的,我尝试用CURL发送相同的头,就像Mozilla一样:失败、管道破裂等等。我删除了一半头:好的。我一个接一个地补充说:失败。删除了另一半的标题:好的。。。所以,只有当标题太长时,才会出现错误。宾果

正如我所说,嵌入式设备中的内存非常少。因此,我不读取整个请求头,只读取其中的256字节。我只需要GET params和“Host”头(即使我真的不需要它,也只是为了使用相同的“Host”而不是IP地址执行重定向)

因此,如果我不()接收整个请求头,我就不能()返回整个响应


谢谢你们的建议,伙计们

您还应该检查
close()
的返回值。它可以检测
send()
成功返回后发生的错误。Thx,我已经检查过了,close()上没有错误。(正如我们所预料的,curl工作得很好。)好吧,您正在寻找
curl
与浏览器之间的区别。如果浏览器在读取所有数据之前导致套接字出错,则浏览器可能会在
close()
中显示该错误,但不会在curl中显示该错误。可能浏览器在完成写入请求之前不会开始读取响应。由于没有读取整个请求,您阻止了浏览器的发送,这意味着您的发送在填满所有可用缓冲区后立即被阻止。呃,我没有找到其他方法来解决此问题。