C++ 破损的HTML-浏览器不';t从我的Web服务器下载整个HTTP响应,CURL则下载 症状
我想,我搞砸了,因为Mozilla Firefox和Google Chrome都产生了相同的错误:它们没有收到Web服务器发送给它们的全部响应。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... )
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中显示该错误。可能浏览器在完成写入请求之前不会开始读取响应。由于没有读取整个请求,您阻止了浏览器的发送,这意味着您的发送在填满所有可用缓冲区后立即被阻止。呃,我没有找到其他方法来解决此问题。