分块的流响应不正确

时间:2018-09-09 18:39:12

标签: c# tcp stream chunked

抱歉,标题如此含糊,我真的不知道该题目的标题。 基本上,当我得到如Transfer-Encoding告知的那样被分块的流时,然后执行以下代码:

decimal

这是从流中读取1行数据,该数据应为“块的长度”,在此进行一些检查,但最终将其转换为Int32 Radix16整数。

从那里开始,它实际上创建了一个int32的字节缓冲区作为其长度大小。

然后,它会一直从流中读取数据,直到其读取的数据量与我们转换的Int32相同为止。

这很出色,但是,无论出于何种原因,它在上次读取时的响应均不正确。

它将读取确切的字节数,因为块长度非常合适,并且读取了我期望的所有数据。但是,它还再次读取了最后已经读取的另一小块数据,因此可以说从DateTimestring的所有数据都像{{1} }等

这是发生的事的一个例子:

enter image description here

如您所见,突出显示的红色文本不应从阅读中返回!它应该以{{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而不是分块编码,或者可能使用较小的分块,以便您始终在第一次读取时就获得完整的分块。