HttpWebResponse 和分块 http。如何读取单个块?

发布于 2024-09-18 22:39:30 字数 148 浏览 3 评论 0原文

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

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

There's a binary file on a remote server, that I wish to stream to my client.
I issue a GET request and the response is an HTTP header + body that has the binary file, in chunks.
The problem is, each chunk contains as well as the binary data, some metadata that I need.

How can I read just ONE chunk at a time from the HTTP stream with C#?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

山色无中 2024-09-25 22:39:30

Ani 的解决方案不会为您解决这个问题,因为您的问题不是将其流式传输,而是访问原始的协议级块。除非将元数据添加到返回的标头中(我怀疑情况并非如此),否则您唯一的选择可能是下降到套接字级别并实现您自己的 HTTP 客户端代码。根据您对功能的限制程度以及您对协议的舒适程度,这可能并不难。

编辑

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

现在,如果您要读取并包括第一个块标头,它将包含该块的长度,因此您可以准确地知道直到块末尾为止可以读取多少字节。我相信,但我不确定,如果您尝试读取该块的末尾并且未发送下一个块,Socket.Receive 将读取尽可能多的内容并返回实际字节数。无论如何,如果您小心的话,您将能够在第二个块仍在发送时开始处理第一个块。

这有帮助吗?

Ani's solution isn't going to cut it for you, because your problem isn't about streaming it in, but rather getting access to the original, protocol-level chunks. Unless the metadata is added to the returned headers, which I suspect is not the case, your only choice might be to drop down to the socket level and implement your own HTTP client code. Depending on how mich you can constrain the functionality and your own comfort with protocols, this might not be so hard.

edit

If you opened up a socket, sent a well-formed HTTP 1.1 request and then read everything back, you would find the initial response headers followed by some number of chunks. Each chunk has its mini-header, followed by the associated data. If you want information in those mini-headers, it's there for you, but you'd have to parse it all out for yourself, just as you'd have to parse the response header. These details are all handled for you when you use a high-level protocol class, but then again, the details are also hidden from you, which is a problem for your special needs.

Now, if you were to read up to and including the first chunk header, it would contain the length of that chunk, so you'd know exactly how many bytes you can read until the end of the chunk. I believe, but I'm not certain, that if you tried to read past the end of that chunk and the next chunk wasn't sent, Socket.Receive would read as much as it can and return the actual byte count. In any case, if you were careful, you would be able to start processing the first chunk while the second was still being sent.

Does that help?

眼眸里的快感 2024-09-25 22:39:30

正如其他人指出的那样,不可能发出 Read() 并期望取回一大块数据。 HTTP 使用 TCP,这是一种流式传输协议。这意味着,如果发送方写入 1024 字节,则读取器可以通过 1024 次读取 1 字节或 1 次读取 1024 字节或介于两者之间的任何值来获取数据。

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

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

As others have pointed out, it is not possible to issue a Read() and expect to get back one chunk of data. HTTP uses TCP which is a streaming protocol. THis means that if the sender wrote 1024 bytes, then the reader counld get the daata in 1024 reads of 1 byte, or 1 read of 1024 bytes or anything in between.

Also due to this reason, even going down to Sockets wont help, since the underlying protocol is still TCP.

SO, you have to do it the hard way. You will have to write a state machine that first does enough Read() to get the required amount of bytes that contain the metadata. Parse this byte array and get the metadata. Then, buffer the remaining (if any) and continue reading to get the Data part. Lather, rinse, repeat...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文