none
C# Web Client Exception: The underlying connection was closed RRS feed

  • Question

  • when my below code is executing then some time i am getting The underlying connection was closed exception and root element is missing.

    public ShippingAcceptResult ShippingAccept(string acceptDigestCode)
    {
        requestType = ShipRequestTypes.ShipAccept;
    
        xmlRequest = new System.Xml.XmlDocument();
        xmlRequest.LoadXml(@"<?xml version=""1.0""?>
         <ShipmentAcceptRequest>
           <Request>
              <TransactionReference>
                 <CustomerContext>TR01</CustomerContext>
                 <XpciVersion>1.0001</XpciVersion>
              </TransactionReference>
              <RequestAction>ShipAccept</RequestAction>
              <RequestOption>01</RequestOption>
           </Request>
           <ShipmentDigest>" + acceptDigestCode + "</ShipmentDigest></ShipmentAcceptRequest>");
    
        byte[] bb = new System.Text.ASCIIEncoding().GetBytes(string.Format(XML_CONNECT, sAccessCode.Trim(), sUserId.Trim(), sPassword.Trim()));
    
        System.IO.MemoryStream ms = new System.IO.MemoryStream();
        ms.Write(bb, 0, bb.Length);
        xmlRequest.Save(ms);
        bb = ms.ToArray();
        System.Net.WebClient wc = new System.Net.WebClient();
        xmlRespone = new XmlDocument();
        //System.Web.HttpContext.Current.Response.Write(System.Text.ASCIIEncoding.ASCII.GetString(wc.UploadData(UPS_URL, "POST", bb)));
        string serverName = (testMode) ? "wwwcie" : "www";
    
        serverName = string.Format(UPS_SERVICE_URL, serverName, ShipRequestTypes.ShipAccept);
        xmlRespone.LoadXml(System.Text.ASCIIEncoding.ASCII.GetString(wc.UploadData(serverName, "POST", bb)));
        //xmlRespone.Save(@"d:\shippingresponseAccept.xml");
        return new ShippingAcceptResult(xmlRespone);
    }

    so i search google and found few SO link there. they are telling to set KeepAlive = false; and i did it. here is the url from where i took the help https://stackoverflow.com/a/24719999/728750

    also i checked few other SO link they are saying increase timeout. those url are

    https://stackoverflow.com/a/6994391/728750 https://stackoverflow.com/a/3052637/728750 https://stackoverflow.com/a/1530717/728750

    var request = (HttpWebRequest)WebRequest.Create(remoteUri);
    request.Timeout = 30000;

    so i just need to know if i set KeepAlive = false; is it enough or also do i need to set Timeout too along with KeepAlive

    please guide me. thanks

    Wednesday, November 1, 2017 8:37 AM

Answers


  • Hi Sudip_inn,

    >>so i just need to know if i set KeepAlive = false; is it enough or also do i need to set Timeout too along with KeepAlive

    Http specifies that it is stateless, that is, after processing a request and return, the server side should directly close the TCP connection, regardless of whether the same client to send the request again.

    In HTTP 1.0, the keep-alive message is inserted through the header to indicate a persistent connection
    HTTP 1.1 is a persistent connection by default.

    HttpWebRequest.KeepAlive Property:Gets or sets a value that indicates whether to make a persistent connection to the Internet resource.

    HttpWebRequest.Timeout Property :Gets or sets the time-out value in milliseconds for the GetResponse and GetRequestStream methods.

    So, As far as I know, KeepAlive and Timeout are not necessarily related. You needn't set Timeout too along with KeepAlive.

    But, if there are too many connections(KeepAlive = true) of the http (according to your website server). Your web request(GetResponse) will have a risk of overtime. So, you may need to set Timeout Property. When you set KeepAlive = false, the server side will close the TCP connection timely, The risk of requesting a timeout is small.

    If you want to learn more about the principles and explanations, you can go to the ASP.NET forum.

    Best Regards,

    Yohann Lu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Thursday, November 2, 2017 6:13 AM
    Moderator

  • Hi Sudip_inn,

    >>should i use both option in my code means do i need to set keepalive false and connection timeout or one is suffice ?

    As far as I know, You can set both options in your code. but, more settings may depend on the Web server's settings. Because the Web server settings will affect the client request.

    So, I suggest you can go to the ASP.NET forum to get more about the principles and explanations.

    The Visual C# discuss and ask the C# programming language, IDE, libraries, samples and tools .

    Your understanding and cooperation will be grateful.

    Best Regards,

    Yohann Lu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Sudip_inn Friday, November 3, 2017 12:45 PM
    Friday, November 3, 2017 3:14 AM
    Moderator

All replies


  • Hi Sudip_inn,

    >>so i just need to know if i set KeepAlive = false; is it enough or also do i need to set Timeout too along with KeepAlive

    Http specifies that it is stateless, that is, after processing a request and return, the server side should directly close the TCP connection, regardless of whether the same client to send the request again.

    In HTTP 1.0, the keep-alive message is inserted through the header to indicate a persistent connection
    HTTP 1.1 is a persistent connection by default.

    HttpWebRequest.KeepAlive Property:Gets or sets a value that indicates whether to make a persistent connection to the Internet resource.

    HttpWebRequest.Timeout Property :Gets or sets the time-out value in milliseconds for the GetResponse and GetRequestStream methods.

    So, As far as I know, KeepAlive and Timeout are not necessarily related. You needn't set Timeout too along with KeepAlive.

    But, if there are too many connections(KeepAlive = true) of the http (according to your website server). Your web request(GetResponse) will have a risk of overtime. So, you may need to set Timeout Property. When you set KeepAlive = false, the server side will close the TCP connection timely, The risk of requesting a timeout is small.

    If you want to learn more about the principles and explanations, you can go to the ASP.NET forum.

    Best Regards,

    Yohann Lu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Thursday, November 2, 2017 6:13 AM
    Moderator
  • i just like to know what is the problem of having persistent connection. first did not set any keepalive=true or false.

    but some time i was getting a exception called The underlying connection was closed. does it occur only that i did not set keepalive false ?

    SO forum suggested to set it false to avoid connection error.

    should i use both option in my code means do i need to set keepalive false and connection timeout or one is suffice ?

    guide me please. thanks

     
    Thursday, November 2, 2017 11:47 AM

  • Hi Sudip_inn,

    >>should i use both option in my code means do i need to set keepalive false and connection timeout or one is suffice ?

    As far as I know, You can set both options in your code. but, more settings may depend on the Web server's settings. Because the Web server settings will affect the client request.

    So, I suggest you can go to the ASP.NET forum to get more about the principles and explanations.

    The Visual C# discuss and ask the C# programming language, IDE, libraries, samples and tools .

    Your understanding and cooperation will be grateful.

    Best Regards,

    Yohann Lu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Sudip_inn Friday, November 3, 2017 12:45 PM
    Friday, November 3, 2017 3:14 AM
    Moderator
  • actually these line of code solve my issue

    ServicePointManager.SecurityProtocol = (SecurityProtocolType)768 | (SecurityProtocolType)3072; //768 for TLS 1.1 and 3072 for TLS 1.2
    //ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate;
    //System.Net.ServicePointManager.ServerCertificateValidationCallback += (send, certificate, chain, sslPolicyErrors) => { return true; };
    System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

    few more code snippet i used along with ServicePointManager

    using (var client = new NoKeepAlivesWebClient())
    {
        bResponse = client.UploadData(serverName, "POST", bb);
    }
    
    /// Certificate validation callback.
    /// </summary>
    private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
    {
        // If the certificate is a valid, signed certificate, return true.
        if (error == System.Net.Security.SslPolicyErrors.None)
        {
        return true;
        }
    
        Console.WriteLine("X509Certificate [{0}] Policy Error: '{1}'",
        cert.Subject,
        error.ToString());
    
        return false;
    }
    
    public class NoKeepAlivesWebClient : WebClient
    {
        protected override WebRequest GetWebRequest(Uri address)
        {
            var request = base.GetWebRequest(address);
            if (request is HttpWebRequest)
            {
            ((HttpWebRequest)request).KeepAlive = false;
            ((HttpWebRequest)request).Timeout = 60000;
            }
    
            return request;
        }
    }


    • Edited by Sudip_inn Monday, November 13, 2017 11:58 AM
    Tuesday, November 7, 2017 12:59 PM