2

症状

我想,我搞砸了,因为 Mozilla Firefox 和 Google Chrome 都会产生相同的错误:它们没有收到网络服务器发送给它们的全部响应。CURL 永远不会错过,快速滚动响应的最后一行始终是"</html>"

原因

原因是,我更多地发送响应:

    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()调用之间停止接收数据。此外,网络服务器不会关闭()套接字,只是在最后。

(我为什么这样做:我写的程序是为非linux系统设计的,它会在嵌入式计算机上运行。它没有太多的内存,主要被lwIP堆栈占用。所以,避免收集 -相对 - 巨大的网页,我分部分发送。像它这样的浏览器,没有像在 Linux 下那样发生损坏的 HTML。)

环境

该平台是 GNU/Linux(Ubuntu 32 位和 3.0 内核)。我的小型网络服务器将这些东西发送回客户端标准方式:

    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()发送整个响应吗?(我现在正在努力,直到一个快速的解决方案到来。)

4

2 回答 2

1

如果您阅读 RFC 2616,您会发现应该使用CR+LF行尾。

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

于 2012-05-15T09:29:53.093 回答
0

明白了!

正如@Jim 建议的那样,我尝试使用 CURL 发送相同的标头,就像 Mozilla 所做的那样:失败、损坏的管道等。我已经删除了一半的标头:好的。我已经一一补充了:失败。删除了另一半标题:好的......所以,只有当标题太长时才会出错。答对了。

正如我所说,嵌入式设备中的内存量非常小。所以,我没有阅读整个请求头,只有 256 个字节。我只需要 GET 参数和“Host”标头(即使我真的不需要它,只是用相同的“Host”而不是 IP 地址执行重定向)。

所以,如果我不recv()整个请求标头,我就不能send()回整个响应

谢谢你的建议,伙计们!

于 2012-05-15T10:29:33.273 回答