Monday, February 7, 2022

C# HttpWebRequest Errors/times out if there is no response from the server in about 10 minutes

HttpWebRequest will throw error as below in about 10 minutes even though the API call is still running. There is no error shown in the server, and the server API continues to run even after this error is seen in client. This can be seen in nodjs servers processing long running logic, and sending no responses back while doing so

System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   --- End of inner exception stack trace ---
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count)
   at System.Net.Security._SslStream.StartFrameHeader(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security._SslStream.StartReading(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security._SslStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.TlsStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.PooledStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.Connection.SyncRead(HttpWebRequest request, Boolean userRetrievedStream, Boolean probeRead)
   --- End of inner exception stack trace ---
   at System.Net.HttpWebRequest.GetResponse()
   at ST_21897f924a0740cf89b833f682f079d9.ScriptMain.HttpGet(String url)

A solution is to change Tcp wait timeout as below. You may also need to set correct timeout for the HttpWebRequest or else it may timeout with System.Net.WebException: The operation has timed out. Make sure this is set before the HttpWebRequest object is created.

ServicePointManager.FindServicePoint(new Uri(url)).SetTcpKeepAlive(true, 6000, 3000);

 

A sample request with this as below 

public string HttpGet(string url)
{
    string result = null;
    ServicePointManager.Expect100Continue = true;
    var sp = ServicePointManager.FindServicePoint(new Uri(url));
    sp.SetTcpKeepAlive(true, 6000, 3000);
    ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
    HttpWebRequest req = WebRequest.Create(url) as HttpWebRequest;
    req.KeepAlive = false;
    req.Timeout = 7200000;
    using (HttpWebResponse resp = req.GetResponse() as HttpWebResponse)
    {
        using (StreamReader reader =
            new StreamReader(resp.GetResponseStream()))
        {
            result = reader.ReadToEnd();
            reader.Close();
        }
        resp.Close();
    }

    return result;
}

No comments:

Turn on Windows 11 Fast Boot

If windows starting is slow, to enable windows 11 fast startup/boot,  Press Windows + R, type powercfg.cpl, and hit Enter.  This will direct...