HttpWebResponse和chunked http。如何读取一个块?

时间:2010-09-15 14:51:03

标签: c# http httpwebrequest httpwebresponse chunks

远程服务器上有一个二进制文件,我希望将其传输到我的客户端。 我发出一个GET请求,响应是一个HTTP标题+正文,它包含二进制文件。 问题是,每个块都包含二进制数据,以及我需要的一些元数据。

如何使用C#从HTTP流中一次只读取一个块?

2 个答案:

答案 0 :(得分:1)

Ani的解决方案不会为你削减它,因为你的问题不是流式传输,而是访问原始的协议级块。除非将元数据添加到返回的标头中,我怀疑不是这种情况,否则您唯一的选择可能是下拉到套接字级别并实现您自己的HTTP客户端代码。根据您可以通过协议约束功能和自身舒适度的方式,这可能不会那么难。

修改

如果你打开了一个套接字,发送了一个格式正确的HTTP 1.1请求,然后再读回所有内容,你会发现初始响应头后跟一些块。每个块都有其迷你标题,后跟相关数据。如果你想要那些迷你标题中的信息,它就在那里,但是你必须自己解析它,就像你必须解析响应标题一样。当您使用高级协议类时,这些详细信息都会为您处理,但同样,您也会隐藏详细信息,这对您的特殊需求是个问题。

现在,如果您要读取并包含第一个块头,它将包含该块的长度,因此您可以确切地知道在块结束之前可以读取多少字节。我相信,但我不确定,如果您尝试读取该块的末尾并且未发送下一个块,Socket.Receive将尽可能多地读取并返回实际的字节数。在任何情况下,如果你小心,你将能够开始处理第一个块,而第二个块仍然被发送。

这有帮助吗?

答案 1 :(得分:1)

正如其他人所指出的那样,不可能发出Read()并期望获得一块数据。 HTTP使用TCP作为流协议。这意味着如果发送者写入了1024个字节,那么读者会得到1024个1字节读取或1个1024字节读取或其间任何内容的数据。

同样由于这个原因,即使转到套接字也无济于事,因为底层协议仍然是TCP。

所以,你必须以艰难的方式去做。您必须编写一个状态机,它首先执行足够的Read()以获取包含元数据所需的字节数。解析此字节数组并获取元数据。然后,缓冲剩余的(如果有的话)并继续读取以获取数据部分。泡沫,冲洗,重复...