c - C中的HTTP/1.0服务器,如何向客户端发送大文件?

标签 c file http server

我必须(作为一项任务)用 C 语言编写一个小型 HTTP/1.0 服务器。

这是我的问题:我不知道如何处理客户端请求的页面尺寸非常大的情况。

我认为最好先读取整个文件,然后开始向客户端发送回复(包括状态行和标题),主要原因是我可以适本地设置状态码。例如,假设服务器已经读取并存储为客户端想要的文件的一半字符串,read() 失败。然后我会继续并将“HTTP/1.0 500 内部服务器错误”设置为状态行。

这种方法的问题是,如果文件很大,它会占用太多内存(并且由于每个连接都由一个单独的线程处理,如果多个线程要将相当大的文件存储为字符串,内存使用量会增加更糟)。

作为一个解决方案,我考虑打开文件,发送状态行和标题,然后将给定数量(不要太大)的字节读入缓冲区并迭代发送缓冲区中的内容,直到我读取/发送了整个文件。

这解决了问题,但是,如果 read() 在我读到文件的一半时失败怎么办?由于内部错误,客户端请求无法完成,因此 500 状态代码是合适的,但我已经通过套接字发送了 200 OK 消息!

HTTP 服务器通常如何处理这个问题?

最佳答案

As a solution I thought about opening the file, sending the status line and the headers, then read into a buffer a given amount (not too large) of bytes and iteratively send what is in the buffer until I've read/sent the whole file.

这正是您应该做的。事先查询文件大小,以便将其放入 Content-Length 响应 header ,然后在发送了那么多字节后停止读取+发送循环。

如果您可以切换到 HTTP 1.1,那么您还有另一种选择。您可以省略 Content-Length header ,而是发送 Transfer-Encoding: chunked header ,然后您可以以 chunked 格式发送每个缓冲区(参见 RFC 2616 Section 3.6.1 ),其中每个 block 指定其自己的字节大小。数据传输通过发送一个 0 长度的 block 来终止。这允许您在不知道总大小的情况下发送/流式传输大量数据。但是这个选项在 HTTP 1.0 中不可用。

This solves the problem, but again, what if read() fails while I'm halfway through the file?

您唯一能做的就是关闭套接字以表示传输已终止。如果您发送一个 Content-Length header (或者在 HTTP 1.1 分块的情况下,发送一个 0 长度的 block ),客户端将知道它何时收到正确的文件结尾,以及过早的关闭是一个错误。但是如果没有这些信息,套接字关闭是表示传输结束的唯一方法,客户端将无法知道它是成功还是错误(HTTP 1.1 确实有能力恢复中断的下载,但是HTTP 1.0 没有)。

The client request could not be fulfilled because of an internal error, thus a 500 status code would be appropriate, but I've already sent a 200 OK message through the socket!

一旦发送,您就无法更改回复状态。但是,如果您让客户端知道它如何检测文件的正确结尾,它就会知道如何检测损坏的下载。

关于c - C中的HTTP/1.0服务器,如何向客户端发送大文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36096926/

相关文章:

c - 需要帮助理解这些 for 循环输出

java - 如何使用文件读取器和字符数组拼凑字符串

java - 无法在 Arquillian 测试中打开资源文件

python - 如何在 python + twisted 中检测 HTTP 请求?

c - Sublime Text 2 : Having trouble making an OpenGL sublime-build

c - 将 typedef 函数指针作为参数传递问题

c - 原子地覆盖指针

delphi - 替换文件中的字符(更快的方法)

powershell - 休息 API : adapt a curl post to powershell

c# - .NET 紧凑型框架 - "offline webservices"支持