2017-03-09 33 views
0

我在外部服務器(IIS)上部署了客戶端桌面應用程序和Web服務。它們之間的通信基於HttpWebRequest和HttpWebResponse。 此代碼在IIS 8.0上正常工作,並將其升級到IIS 8.5後,將響應發送回客戶端停止工作。下面拋出異常在客戶端:IIS網頁響應連接強制關閉問題

System.IO.IOException:無法從傳輸 連接讀取數據:
一個現有的連接強制關閉由 遠程主機。 --->
System.Net.Sockets.SocketException:
一個 現有連接被遠程主機強制關閉
在 System.Net.Sockets.Socket.Receive(Byte []緩衝區,Int32偏移量,Int32 大小,的SocketFlags的SocketFlags)
在 System.Net.Sockets.NetworkStream.Read(字節[]緩衝液,的Int32偏移, 的Int32大小)
---內部異常堆棧跟蹤的結尾---

在System.Net.ConnectStream .Read(Byte []緩衝區,Int32偏移量,Int32 大小)
at System.IO.Stream.InternalCopyTo(Stream destination, Int32 bufferSize)
at Test.TestH ttpService.GetResponseString(HttpWebResponse響應)

在服務器端不會引發異常。服務器上的Wireshark和客戶機上的Fiddler也沒有提供任何線索。 IIS跟蹤日誌表明所有數據已經​​成功發送到客戶端

enter image description here

客戶端代碼:

public static string GetResponse(string serviceUrl, string resourceUrl, string method, string xmlRequestBody, string authorization, string connectionName) 
    { 
     string responseMessage = null; 
     ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3; 
     var request = HttpWebRequest.Create(string.Concat(serviceUrl, resourceUrl)) as HttpWebRequest; 
     if (request != null) 
     { 
      request.ContentType = "application/xml"; 
      request.Method = method; 
      request.KeepAlive = false; 
      request.ProtocolVersion = HttpVersion.Version10; 
      request.Timeout = int.MaxValue; 
      //request.ServicePoint.ConnectionLimit = 1; 
      request.Headers.Add("Authorization", authorization); 
      request.Headers.Add("ConnectionName", connectionName); 
     } 

     if (xmlRequestBody != null) 
     { 
      byte[] requestBodyBytes = TBCCompressionService.Zip(xmlRequestBody.ToString()); 
      request.ContentLength = requestBodyBytes.Length; 
      if (request.ContentLength > 0) 
      { 
       using (Stream postStream = request.GetRequestStream()) 
       { 
        postStream.Write(requestBodyBytes, 0, requestBodyBytes.Length); 
       } 
      } 
     } 

     if (request != null) 
     { 
      System.Net.ServicePointManager.Expect100Continue = false; 
      try 
      { 
       var response = request.GetResponse() as HttpWebResponse; 
       if (response.StatusCode == HttpStatusCode.OK) 
       { 
        responseMessage = GetResponseString(response); 
       } 
       else 
       { 
        responseMessage = response.StatusDescription; 
       } 
      } 
      catch(WebException ex) 
      { 
       var httpResponse = ex.Response as HttpWebResponse; 
       if (httpResponse != null 
        && httpResponse.StatusCode == HttpStatusCode.BadRequest) 
       { 
        responseMessage = GetResponseString(ex.Response as HttpWebResponse); 
       } 
       else 
       { 
        throw ex; 
       } 
      } 
     } 
     return responseMessage; 
    } 
private static string GetResponseString(HttpWebResponse response) 
    { 
     string result = string.Empty; 

     if(response != null) 
     { 
      using (Stream responseStream = response.GetResponseStream()) 
      { 
       if (responseStream != null) 
       { 
        using (MemoryStream memoryStream = new MemoryStream()) 
        { 
         //this is the line when above exception is thrown. 
         responseStream.CopyTo(memoryStream); 
         result = TBCCompressionService.UnZip(memoryStream.ToArray()); 
        } 
       } 
      } 
     } 
     return result; 
    } 

服務器端代碼:

public static void Send(string responseContent, HttpStatusCode? httpStatus) 
{ 
    HttpResponse response = HttpContext.Current.Response; 
    int waitCounter = 1000; 
    if (response.IsClientConnected) 
    { 
     response.Clear(); 
     response.BufferOutput = true; 
     response.Buffer = true; 

     if (httpStatus != null) 
     { 
      response.StatusCode = (int)httpStatus.Value; 
     } 

     if (responseContent == null 
      || string.IsNullOrWhiteSpace(responseContent)) 
     { 
      response.StatusCode = (int)HttpStatusCode.NoContent; 
     } 
     else 
     { 
      byte[] responseContentZip = Zip(responseContent); 
      int responseContentLength = responseContentZip.Length; 
      response.ContentType = "text/xml"; 
      response.AppendHeader("Content-Length", responseContentLength.ToString()); 
      response.BinaryWrite(responseContentZip); 
     } 
      response.Flush(); 
      //If this sleep is not present exception is thrown on the client side 
      //Unable to read data from the transport connection : An existing connection was forcibly closed by the remote host. 
      System.Threading.Thread.Sleep(waitCounter); 
      response.Close(); 
      response.End(); 
    } 
    else 
    { 
     logger.Error("Client was no longer connected to remote server. Response wasn't sent."); 
    } 
} 

非常奇怪的是,睡覺AppPool線程可以幫助並讓響應成功地到達客戶端。 在我看來Flush操作在連接關閉之前並未結束,我在System.Web.dll代碼中查找了一些線索,但沒有指出Flush在這種情況下是異步執行的,或者是在執行期間中斷連接。

+0

你看事件日誌? –

+0

是的,我做了,也沒有線索這個連接發生了什麼。 – RadMi

回答

0

u可以使用限制的服務點的數量

** webRequest.ServicePoint.ConnectionLimit = 1;

**

+0

我已經試過了 - 沒有結果。 – RadMi