0

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

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

4

2 回答 2

1

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

编辑

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

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

这有帮助吗?

于 2010-09-15T18:18:49.710 回答
1

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

同样由于这个原因,即使使用 Sockets 也无济于事,因为底层协议仍然是 TCP。

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

于 2010-09-16T03:47:32.357 回答