Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# HttpWebResponse.GetResponseStream():何时传输响应正文?_C#_.net_Http_Httpwebrequest - Fatal编程技术网

C# HttpWebResponse.GetResponseStream():何时传输响应正文?

C# HttpWebResponse.GetResponseStream():何时传输响应正文?,c#,.net,http,httpwebrequest,C#,.net,Http,Httpwebrequest,我使用该类实现了一个简单的HTTP下载程序,可以暂停、取消,甚至在取消后恢复(使用HTTP范围请求头) 很明显,HttpWebRequest.GetResponse()是HTTP请求实际发送到服务器的时间,该方法在收到HTTP响应(或发生超时)时返回。但是,响应体是用流表示的,这让我想知道响应体是否实际是用响应头传输的(即,当GetResponse()返回时,它已经下载了),还是在我尝试从响应流读取时,它只是按需下载的?或者当我调用HttpWebResponse.GetResponseStrea

我使用该类实现了一个简单的HTTP下载程序,可以暂停、取消,甚至在取消后恢复(使用HTTP范围请求头)

很明显,HttpWebRequest.GetResponse()是HTTP请求实际发送到服务器的时间,该方法在收到HTTP响应(或发生超时)时返回。但是,响应体是用流表示的,这让我想知道响应体是否实际是用响应头传输的(即,当GetResponse()返回时,它已经下载了),还是在我尝试从响应流读取时,它只是按需下载的?或者当我调用HttpWebResponse.GetResponseStream()方法时

不幸的是,msdn文档没有说明问题,而且我对HTTP协议的了解也不足以说明问题


在这种情况下,分块传输等是如何工作的(也就是说,我应该如何在我的C#应用程序中处理它们)?响应数据实际上是什么时候从服务器下载的?

这一切都取决于HTTP的底层协议TCP。TCP的工作方式是以段的形式发送数据。每当客户机向服务器发送一个数据段时,发送的数据中就有关于准备接收多少额外数据的信息。这通常对应于客户端的某种缓冲区。当客户端接收到一些数据时,它还会向服务器发送一个段,确认接收到的数据

因此,假设客户端在处理接收到的数据时非常慢,那么事件的顺序可能是这样的:

  • 连接建立后,客户机会说它准备接收多少数据
  • 服务器向客户端发送一个或多个数据段,这些数据段中的总数据量最多为客户端表示准备接收的数据量
  • 客户对服务器说:我收到了您发送给我的数据,但现在不要再发送给我了
  • 客户机处理一些数据
  • 客户端对服务器说:你可以再给我发送x字节的数据

  • 这对于
    GetResponse()
    意味着什么?当您调用
    GetResponse()
    时,客户机发送请求,读取响应的HTTP头(通常包含在一个段中,但可能更多)并返回。此时,如果您没有开始读取响应流(通过调用
    GetResponseStream()
    ),则会从服务器接收一些数据,但只是为了填充缓冲区。当数据流已满时,在开始读取响应流之前,不会传输更多的数据。

    FWIW,这实际上更多的是关于TCP/IP而不是HTTP。HTTP总是尝试发送完整的响应。您要问的问题是:“无论我是否读取响应流,.NET是否从套接字读取HTTP实体体”,我几乎肯定答案是“是”。因此,如果我理解正确,只有在我从响应流读取时才会发送响应体。这比我想象的要复杂一点,但我明白了。非常感谢。在我接受您的回答之前,还有一个问题:我知道服务器可能会以单独的片段(分块传输)返回数据。在这种情况下,它只是意味着从响应流读取将被阻止,直到下一个块可用,对吗?@ShdNx,这并不准确。即使您没有读取响应流,也会发送部分响应,但很可能不会发送整个响应。分块传输编码实际上不会改变任何东西。即使不使用分块传输,从响应流读取数据块也是正常的。使用分块传输时,流不必阻塞,直到下一个分块全部可用,直到部分可用为止。