Ric*_*ahl 14 .net c# dotnet-httpclient
我正在尝试使用新的HttpClient类(在.NET 4.5中)从服务器检索部分响应以检查内容.我需要将检索到的数据大小限制为HTTP请求中内容的前几个字节,以限制带宽使用.
我一直无法做到这一点.我尝试过使用GetAsync(url,HttpCompletionOption.ResponseHeadersRead),然后使用Content.ReadAsStream()尝试只读取标题,然后在一个小块中读取响应流.我还尝试了GetStreamAsync(),然后用一小块(1000字节)读取内容流.
在这两种情况下,HttpClient似乎都在拉动和缓冲整个HTTP响应,而不仅仅是从流中读取请求的字节数.
最初我使用Fiddler监控数据,但意识到Fiddler实际上可能导致整个内容被代理.我切换到使用System.Net跟踪(显示):
ConnectStream#6044116::ConnectStream(Buffered 16712 bytes.)
Run Code Online (Sandbox Code Playgroud)
这是完整的大小,而不仅仅是读取的1000个字节.我还对Wireshark进行了双重检查,以确认是否确实通过电线拉出了全部内容.对于更大的内容(如110k链接),我会在截断TCP/IP流之前获得大约20k的数据.
我试图读取数据的两种方式:
response = await client.GetAsync(site.Url, HttpCompletionOption.ResponseHeadersRead);
var stream = await response.Content.ReadAsStreamAsync();
var buffer = new byte[1000];
var count = await stream.ReadAsync(buffer, 0, buffer.Length);
response.Close() // close ASAP
result.LastResponse = Encoding.UTF8.GetString(buffer);
Run Code Online (Sandbox Code Playgroud)
和:
var stream = await client.GetStreamAsync(site.Url);
var buffer = new byte[1000];
var count = await stream.ReadAsync(buffer, 0, buffer.Length);
result.LastResponse = Encoding.UTF8.GetString(buffer);
Run Code Online (Sandbox Code Playgroud)
它们都产生几乎相同的.NET跟踪,包括缓冲读取.
是否有可能让HttpClient实际只读取一小部分Http Repsonse,而不是整个响应以便不使用全带宽?IOW有没有办法使用HttpClient或HttpWebRequest禁用HTTP连接上的任何缓冲?
更新: 经过一些更广泛的测试后,看起来HttpClient和HttpWebRequest都会缓冲前几个TCP/IP帧 - 可能是为了确保捕获HTTP头.因此,如果你返回一个足够小的请求,它往往会被完全加载,因为它是在初始缓冲读取中.但是,当加载更大的内容网址时,内容会被截断.对于HttpClient来说,它约为20k,对于HttpWebRequest来说,对我来说大约是8k.
使用TcpClient没有任何缓冲问题.使用它时,我会以读取的大小读取内容,加上最近的缓冲区大小重叠,但这包括HTTP标头.使用TcpClient对我来说不是一个真正的选择,因为我们必须处理SSL,重定向,Auth,Chunked内容等.此时我会考虑实现一个完整的自定义HTTP客户端,只是为了转向缓冲.
小智 1
我可能是错的,但我认为你感到困惑:当你向服务器发送请求时,它会通过网络向你发送完整的答案。然后它由框架缓冲在某个地方,您可以使用流访问它。如果您不希望远程服务器向您发送完整答案,您可以使用 http 标头指定所需的字节范围。例如,请参阅HTTP 状态:206 部分内容和范围请求。
| 归档时间: |
|
| 查看次数: |
6846 次 |
| 最近记录: |