如何使用NetworkStream读取以获得完整的HTTP响应(代理)?

时间:2018-02-20 23:11:34

标签: c# http tcp header networkstream

目前我正在构建TCP代理,它通过发送从浏览器到网站的HTTP请求,然后通过以下代码无意中读取它的响应:

byte[] buff = new byte[1024];
NetworkStream stream = tcpclient.GetStream();
using (MemoryStream ms = new MemoryStream())
{
    int length;
    while ((length = tcpclient.Available) > 0)
    {
        length = (length > buff.Length) ? (buff.Length) : (length);
        stream.Read(buff, 0, length);
        ms.Write(buff, 0, length);
    }
    byte[] data = ms.ToArray();
}

但我遇到了问题:
如果网站发送响应太慢而()刚刚被跳过,因为代码在任何数据到达代理之前到达而() Thread.Sleep()显然不是解决方案,因为我需要在数据到达时立即获取数据以及某些网站可能会有很大的延迟。
我认为我可以通过设置最小数据大小来绕过这个问题,这样我就可以获得HTTP响应标头并查找 Content-Size ,但我检查了一些响应和标题大小差别很大,所以 Content-Size 属性可以是第10个字节,也可以是第100个,甚至更多,但另一方面,HTTP响应的大小(标题+正文)小于某些响应的标题。
我也可以使用异步接收来获得更好的结构,但我仍然需要正确的数据大小才能接收。

现在,问题:
1)我应该找到接收的完美字节数来获取我需要的所有标题部分,但不要松散小响应或者有另一种方法可靠地获得整个HTTP响应,无论大小是吗?
2)与HTTP结构更相关的问题 - 我看到了响应,其类型是 chunked 。据我了解,一个大的响应分裂为部分,然后发送给客户端。但是我不确定它是如何工作的 - 是一个发送请求的许多 chunked 响应发送了吗?或者在每个 chunked 响应客户端向服务器发出另一个请求后,向他发送下一个 chunked 响应?基本上我要问的是:来自浏览器的一个HTTP请求是否可能会发送多个来自网站的响应?
3)我甚至可以使用HttpListener而不是TCPlistener来获取请求和响应,这将更容易。但是我看到了一个HttpListener用于代理的主题,最流行的答案是你不应该使用HttpListener,因为它有太多的问题所以建议使用TCPlistener代理。是对的吗?虽然主题很老,但在.NET中可能会有所改变。

我已经阅读了这个主题:How to get all data from NetworkStream,但所有答案都依赖于同样的事情 - 在数据可用的情况下阅读,这对我来说并不像我之前所说的那样。

0 个答案:

没有答案