抱歉,标题如此含糊,我真的不知道该题目的标题。 基本上,当我得到如Transfer-Encoding告知的那样被分块的流时,然后执行以下代码:
decimal
这是从流中读取1行数据,该数据应为“块的长度”,在此进行一些检查,但最终将其转换为Int32 Radix16整数。
从那里开始,它实际上创建了一个int32的字节缓冲区作为其长度大小。
然后,它会一直从流中读取数据,直到其读取的数据量与我们转换的Int32相同为止。
这很出色,但是,无论出于何种原因,它在上次读取时的响应均不正确。
它将读取确切的字节数,因为块长度非常合适,并且读取了我期望的所有数据。但是,它还再次读取了最后已经读取的另一小块数据,因此可以说从DateTime
到string
的所有数据都像{{1} }等
这是发生的事的一个例子:
如您所见,突出显示的红色文本不应从阅读中返回!它应该以{{1}}结尾。 为什么“块长”对我说谎?我如何找到合适的尺寸来阅读?
答案 0 :(得分:0)
我对C#不熟悉,但是如果我正确理解了C#中的代码和Read
的语义(似乎与C中的read
类似),那么问题是一次又一次地使用相同的缓冲区而无需先重置它:
byte[] buffer = new byte[blockLengthInt];
int totalBytesRead = 0;
while (totalBytesRead != blockLengthInt) {
int length = blockLengthInt - totalBytesRead;
int bytesRead = _receiverHelper.HasData ? _receiverHelper.Read(buffer, 0, length) : _request.ClientStream.Read(buffer, 0, length);
...
totalBytesRead += bytesRead;
...
yield return buffer;
}
举一个例子说明这里出了什么问题:假设块大小为10,读取的内容为0123456789
,第一次读取将返回6个字节,第二次读取其余4个字节。在这种情况下,缓冲区将在第一次读取后为012345
,在第二次读取后为567845
。由于您仅替换了缓冲区中的前4个字节,但保留了其余部分,因此缓冲区末尾的45
保留了上一次读取的内容。
奇怪的AF是,如果我将请求交给另一个代理的TCPStream(作为代理的127.0.0.1:8888作为代理),它会很好地工作...
Fiddler是代理,可能会更改响应的传输方式。例如,它可能使用Content-length
而不是分块编码,或者可能使用较小的分块,以便您始终在第一次读取时就获得完整的分块。