我正在使用HttpClient
將數據發送到使用PutAsync
的HTTP服務器。服務器在寫入響應頭後關閉連接時發生HttpClient異常
當服務器發回錯誤代碼(例如401 Unauthorized)時,它關閉連接(在其響應中提供了Connection:close標頭)。發生這種情況時,HttpClient拋出System.Net.Http.HttpRequestException(將內容複製到流時出錯),並列出下面列出的內部異常。這似乎與將數據寫出(儘管它在BeginRead中)有關,因爲如果我說服服務器讀取所有要發送的數據,則不會拋出異常。
我可以通過使用HttpClient.SendAsync
與HttpCompletionOption.ResponseHeadersRead
參數完成相同的任務來解決此問題。在這種情況下,不會拋出異常,我可以閱讀HttpResponseMessage.StatusCode
。
我的問題是,是正確的例外?即服務器是否不遵守標準,通過關閉連接而不讀取所有不需要的數據?如果不是,那麼PutAsync
有沒有問題,因爲在這種情況下它不允許訪問返回StatusCode
?
樣品的編號:
using (FileStream stream = File.OpenRead(FilePath))
using (StreamContent content = new StreamContent(stream))
using (HttpRequestMessage req = new HttpRequestMessage
{
Method = HttpMethod.Put,
RequestUri = new Uri(baseUri, Path),
Content = content,
})
using (HttpClient client = new HttpClient())
{
req.Content.Headers.ContentType = new MediaTypeHeaderValue(FileContentType);
// This version works:
//using (HttpResponseMessage resp = await client.SendAsync(req,
// HttpCompletionOption.ResponseHeadersRead))
// This version throws an exception:
using (HttpResponseMessage resp = await client.PutAsync(
new Uri(baseUri, Path), content))
{
if (resp.StatusCode == HttpStatusCode.Unauthorized)
{
// Try again with authorisation credentials based on resp.Headers.WwwAuthenticate
}
}
}
內部異常信息:System.IO.IOException(無法讀取從傳輸連接數據:一個現有的連接被強行關閉遠程主機)
at System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
at System.Net.PooledStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
at System.Net.ConnectStream.BeginReadWithoutValidation(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
at System.Net.ConnectStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state)
at System.Net.Http.StreamToStreamCopy.StartRead()
內部異常:System.Net.Sockets.SocketException(現有連接被遠程主機強制關閉)
at System.Net.Sockets.Socket.BeginReceive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, AsyncCallback callback, Object state)
at System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)