Search code examples
c#asp.net-web-apisystem.net.sockets

Error: "System.Net.Sockets.SocketException (0x80004005): An existing connection was forcibly closed by the remote host" on test server


I am facing an issue where my Web API is working fine on local systems but creating issues when deployed on server. I have checked, cross-checked multiple times to see if I have missed anything from the config, but everything is in order. Below is the code I am using. The line throwing this error is: using (WebResponse webResponse = webRequest.EndGetResponse(asyncResult))

        public static string PostDataToWebService(string stream, string CustIP)
    {
        var _url = AdditionalSetting.AutoEuroURL;
        string soapResult = string.Empty;
        try
        {
            XmlDocument soapEnvelopeXml = CreateSoapEnvelope(stream);
            HttpWebRequest webRequest = CreateWebRequest(_url, CustIP);
            InsertSoapEnvelopeIntoWebRequest(soapEnvelopeXml, webRequest);
            IAsyncResult asyncResult = webRequest.BeginGetResponse(null, null);
            asyncResult.AsyncWaitHandle.WaitOne();
            using (WebResponse webResponse = webRequest.EndGetResponse(asyncResult))
            {
                using (StreamReader rd = new StreamReader(webResponse.GetResponseStream()))
                {
                    soapResult = rd.ReadToEnd();
                }
            }
        }
        catch (WebException wbex)
        {
            using (var ResStream = wbex.Response.GetResponseStream())
            using (var reader = new StreamReader(ResStream))
            {
                ErrorLog.ErrorLogs("WebException at AutoEurope Call web service : " + reader.ReadToEnd());
            }
        }
        return soapResult;
    }


    private static XmlDocument CreateSoapEnvelope(string stream)
    {

        XmlDocument soapEnvelop = new XmlDocument();
        try
        {
            soapEnvelop.LoadXml(stream);
        }
        catch (Exception ex)
        {

        }
        return soapEnvelop;
    }

    private static HttpWebRequest CreateWebRequest(string url, string CustIP)
    {
        HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
        webRequest.Headers.Add("SOAPAction", "OTA");
        webRequest.Headers.Add("X-Forwarded-For", "\"" + CustIP + "\"");
        webRequest.ContentType = "text/xml;charset=\"utf-8\"";
        webRequest.Accept = "text/xml";
        webRequest.Method = "POST";
        webRequest.KeepAlive = false;
        webRequest.ProtocolVersion = HttpVersion.Version10;
        return webRequest;
    }

    private static void InsertSoapEnvelopeIntoWebRequest(XmlDocument soapEnvelopeXml, HttpWebRequest webRequest)
    {
        using (Stream stream = webRequest.GetRequestStream())
        {
            soapEnvelopeXml.Save(stream);
        }
    }

The CustIP I am getting is the request IP address which I am getting as a parameter in my method. It is in a proper format. Any suggestion would be helpful.


Solution

  • If you're getting this error between the BeginGetResponse() and EndGetResponse(), then there are a few possibilities:

    • A lot of time is passing between the Begin and End, and the server is timing out. This can be checked with extra logging.
    • The server is unhappy with what you have sent it and has closed the connection. Which isn't the problem here as you tested this sucessfully from a different machine.
    • If the URL is an HTTPS URL, then this error can be caused by problems during TLS negotiation. While the TCP connection was established, the client and server couldn't agree on TLS parameters for the connection, and one side closed the connection before your request was sent.

    The best way to check for TLS issues is to log onto to the test server and try to access the URL within a web browser such as Google Chrome or Internet Explorer. You can't use FireFox to test here as FireFox uses it's own implementation of TLS so might be able to succeed where Chrome, IE and .NET cannot.

    If you cannot navigate to the site using a browser, then it most likely:

    • The client doesn't TRUST the certificate that was sent by the server. Normally this is very easy to detect using a web browser, and can be resolved by either getting the server to use a publicly signed certificate, or by you verifying and deciding to trust the root certificate used by the server. This can also be that the server is misconfigured and is not sending an intermediate certificate.
    • The test system and the server do not support the same TLS/SSL versions. TLS v1.2 is the only TLS version that ia considered secure, and many systems are locked down (via the registry) to disable TLS v1.1, v1.0 and SSL v3 and v2.
    • The two systems do not support the same cipher suites. Again this can be because system configuration disallows those ciphers, or the system simply doesn't support them.

    If you have the option of installing WireShark and learning about TLS handshaking, then this may be the quickest way to determine why the systems can't communicate as you can just see the problem directly and it removes a lot of guesswork.

    Often, issues such as this are because either the client or the server are using an obsolete operating system. A Windows 95 client is very unlikely to be able to connect to an HTTPS website running on the latest version of OpenSUSE because they are just too different. Specifically it's unlikely that Windows 95 supports anything other than SSLv3 with basic cipher suites such as RC4, neither of which are likely to be supported on a recent OpenSUSE because they are considered insecure these days. Even Windows Server 2003 is too old to support TLS v1.1 or v1.2. Check the version of the operating system, and again this will be highlighted by WireShark.

    Update

    If you're unable to connect to the service and it's publicly available, you can use the online SSL Tester at https://www.ssllabs.com/ssltest/ to verify that the server is responding correctly.

    In this case (with the address you gave in the comments), the problem is that the server is not responding correctly to any connections, even unsecured HTTP connections to port 80. You would have to contact the server's support department and have them investigate the issue.

    Hope this helps