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

我正在尝试使用我的ASP.NET应用程序调试特定问题 。 客户端运行以下代码:

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()抛出一个exception“无法将数据写入传输连接:已建立的连接被主机中的软件中止。” 文本。 我使用System.Net跟踪 ,发现当我发送Content-Length设置的请求时出现问题。

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

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

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

如何在不关闭连接的情况下重新使用它来重新发送请求?

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

请注意,您确实需要处理request.GetResponse返回的WebResponse – 否则底层基础结构将不会知道您实际上已完成它,并且将无法重用该连接。

BinaryReader ,你为什么要使用BinaryReader ?只需直接使用File.OpenRead返回的流。)

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