我可以在不断开服务器连接的情况下重用HttpWebRequest吗?

时间:2011-02-08 13:12:32

标签: c# .net asp.net iis ssl

我正在尝试调试a specific issue with my ASP.NET application。客户端运行以下代码:

void uploadFile( string serverUrl, string filePath )
{
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.
        Create( serverUrl );
    CredentialCache cache = new CredentialCache();
    cache.Add( new Uri( serverUrl ), "Basic", new NetworkCredential( "User", "pass" ) );
    request.Credentials = cache;
    request.Method = "POST";
    request.ContentType = "application/octet-stream";
    request.Timeout = 60000;
    request.KeepAlive = true;

    using( BinaryReader reader = new BinaryReader( 
        File.OpenRead( filePath ) ) ) {

        request.ContentLength = reader.BaseStream.Length;
        using( Stream stream = request.GetRequestStream() ) {
            byte[] buffer = new byte[1024];
            while( true ) {
                int bytesRead = reader.Read( buffer, 0, buffer.Length );
                if( bytesRead == 0 ) {
                    break;
                }
                stream.Write( buffer, 0, bytesRead );
            }
        }
    }

     HttpWebResponse result = (HttpWebResponse)request.GetResponse();
     //handle result - not relevant
 }

Write()引发异常,“无法将数据写入传输连接:已建立的连接已被主机中的软件中止。”文本。我使用System.Net tracing时发现,当我使用Content-Length设置发送请求时出现问题。

具体来说,如果我省略上面代码中using语句内的所有内容,服务器会立即回复WWW-Authenticate,然后客户端会使用WWW-Authenticate重新发送请求,一切顺利,除了文件未上传,请求失败的时间很晚。

我想执行以下操作:发送没有数据的请求,等待WWW-Authenticate,然后使用WWW-Authenticate和数据重复该请求。所以我尝试修改上面的代码:首先设置所有参数,然后调用GetResponse(),然后执行发送,但是当我尝试设置ContentLength属性时,抛出异常“此属性无法设置写完后已开始“文字。

所以HttpWebRequest似乎是不可重用的。

如何重新发送请求而不关闭连接?

2 个答案:

答案 0 :(得分:16)

您不会重复使用请求 - 顾名思义,这是一个请求。但是,如果您为同一主机发出多个请求,则默认情况下.NET将重用基础网络连接。

请注意,您执行需要处理WebResponse返回的request.GetResponse - 否则底层基础架构将无法知道您实际已完成此操作,并且将无法重复使用该连接。

(顺便说一下,你为什么要使用BinaryReader?直接使用File.OpenRead返回的流。)

答案 1 :(得分:2)

除了Jon Skeet的回答之外,您无需手动设置ContentLength属性。 HttpWebRequest将自动计算并填充该属性。