46

I have the following code:

private Uri currentUri;

private void Form1_Load(object sender, EventArgs e)
{
    currentUri = new Uri(@"http://www.stackoverflow.com");
    HttpWebRequest myRequest = (HttpWebRequest) HttpWebRequest.Create("http://www.stackoverflow.com");
    WebProxy myProxy = new WebProxy("120.198.230.8:81");
    myRequest.Proxy = myProxy;

    HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();

    webBrowser1.DocumentStream = myResponse.GetResponseStream();

    webBrowser1.Navigating += new WebBrowserNavigatingEventHandler(webBrowser1_Navigating);
}

void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
    if (e.Url.AbsolutePath != "blank")
    {
        currentUri = new Uri(currentUri, e.Url.AbsolutePath);
        HttpWebRequest myRequest = (HttpWebRequest)HttpWebRequest.Create(currentUri);

        HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();

        webBrowser1.DocumentStream = myResponse.GetResponseStream();
        e.Cancel = true;
    }
}

after compiling:

error: An unhandled exception of type 'System.Net.WebException' occurred in System.dll

Additional information: The underlying connection was closed: An unexpected error occurred on a receive.

at line HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();

Please help me.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Thomas
  • 463
  • 1
  • 4
  • 5

9 Answers9

78

Setting the HttpWebRequest.KeepAlive to false didn't work for me.

Since I was accessing a HTTPS page I had to set the Service Point Security Protocol to Tls12.

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Notice that there are other SecurityProtocolTypes: SecurityProtocolType.Ssl3, SecurityProtocolType.Tls, SecurityProtocolType.Tls11

So if the Tls12 doesn't work for you, try the three remaining options.

Also notice that you can set multiple protocols. This is preferable on most cases.

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

Edit: Since this is a choice of security standards it's obviously best to go with the latest (TLS 1.2 as of writing this), and not just doing what works. In fact, SSL3 has been officially prohibited from use since 2015 and TLS 1.0 and TLS 1.1 will likely be prohibited soon as well. source: @aske-b

Community
  • 1
  • 1
Bartho Bernsmann
  • 2,393
  • 1
  • 25
  • 34
  • 5
    While this was a fix for a recent scenario we had with this issue, our root cause was a server-side change that disabled support for TLS 1.0. So there may be multiple fixes depending on your scenario. – Sam Storie May 15 '17 at 15:47
  • Nice to know. I actually had this issue while accessing data from a 3rd party server, so I didn't have any control over their TLS support. – Bartho Bernsmann May 15 '17 at 16:47
  • Where should I add this ? – Moeez Apr 11 '19 at 05:00
  • @Faisal: Before the HttpWebRequest – Bartho Bernsmann Apr 16 '19 at 23:46
  • I faced the same error when I was downloading any version of SQL Server from online Installer, turns out I had Disabled the TLS 1.0 (Client & Server Both) from Registry ( Part of Vulnerability Fix), due to which the issue was occurring, After enabling and restart of windows, Issue resolved. thanks – rvsingh42 Aug 28 '20 at 08:17
29

The underlying connection was closed: An unexpected error occurred on a receive.

This problem occurs when the server or another network device unexpectedly closes an existing Transmission Control Protocol (TCP) connection. This problem may occur when a time-out value on the server or on the network device is set too low. To resolve this problem, see resolutions A, D, E, F, and O. The problem can also occur if the server resets the connection unexpectedly, such as if an unhandled exception crashes the server process. Analyze the server logs to see if this may be the issue.

Resolution

To resolve this problem, make sure that you are using the most recent version of the .NET Framework.

Add a method to the class to override the GetWebRequest method. This change lets you access the HttpWebRequest object. If you are using Microsoft Visual C#, the new method must be similar to the following.

class MyTestService:TestService.TestService
{
    protected override WebRequest GetWebRequest(Uri uri)
    {
        HttpWebRequest webRequest = (HttpWebRequest) base.GetWebRequest(uri);
        //Setting KeepAlive to false
        webRequest.KeepAlive = false;
        return webRequest;
    }
}

Excerpt from KB915599: You receive one or more error messages when you try to make an HTTP request in an application that is built on the .NET Framework 1.1 Service Pack 1.

Andrew T.
  • 4,701
  • 8
  • 43
  • 62
Nagaraj S
  • 13,316
  • 6
  • 32
  • 53
  • @Raji You have to write this before you calling HttpWebRequest – Nagaraj S Apr 23 '18 at 11:56
  • @Nagaraj can u plz tell me what am I missing in the code in the below mentioned url https://stackoverflow.com/questions/49978481/when-uploading-file-in-ftp-got-error-the-underlying-connection-was-closed-an?noredirect=1#comment86974929_49978481 – Raji Apr 23 '18 at 12:28
  • 2
    KB excerpt above is a link to a non-existing web page. – Su Llewellyn Apr 27 '21 at 16:06
7
  • .NET 4.6 and above. You don’t need to do any additional work to support TLS 1.2, it’s supported by default.
  • .NET 4.5. TLS 1.2 is supported, but it’s not a default protocol. You need to opt-in to use it. The following code will make TLS 1.2 default, make sure to execute it before making a connection to secured resource:
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12

  • .NET 4.0. TLS 1.2 is not supported, but if you have .NET 4.5 (or above) installed on the system then you still can opt in for TLS 1.2 even if your application framework doesn’t support it. The only problem is that SecurityProtocolType in .NET 4.0 doesn’t have an entry for TLS1.2, so we’d have to use a numerical representation of this enum value:
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12

  • .NET 3.5 or below. TLS 1.2 is not supported. Upgrade your application to more recent version of the framework.

  • 1
    The bullets above are not entirely correct for older .Net Versions, for older versions you can set the TLS manually. ServicePointManager.SecurityProtocol = (System.Net.SecurityProtocolType) 3072; // Aka Tls12 – phanf Jan 06 '20 at 20:32
  • You talk about a *default* protocol version. Does that mean the global setting in `ServicePointManager` can be overridden at any specific use of, say, `HttpWebRequest`? – Anton Shepelev Jul 17 '20 at 15:18
1

None of the solutions out there worked for me. What I eventually discovered was the following combination:

  • Client system: Windows XP Pro SP3
  • Client system has .NET Framework 2 SP1, 3, 3.5 installed
  • Software targeting .NET 2 using classic web services (.asmx)
  • Server: IIS6
  • Web site "Secure Communications" set to:
    • Require Secure Channel
    • Accept client certificates

enter image description here

Apparently, it was this last option that was causing the issue. I discovered this by trying to open the web service URL directly in Internet Explorer. It just hung indefinitely trying to load the page. Disabling "Accept client certificates" allowed the page to load normally. I am not sure if it was a problem with this specific system (maybe a glitched client certificate?) Since I wasn't using client certificates this option worked for me.

Hugh Jeffner
  • 2,936
  • 4
  • 32
  • 31
1

My Hosting server block requesting URL And code site getting the same error 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

enter image description here

After a lot of time spent and apply the following step to resolve this issue

  1. Added line before the call web URL

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

  2. still issue not resolve then I upgrade .net version to 4.7.2 but I think it's optional

  3. Last change I have checked my hosting server security level which causes to TLS handshaking for this used "https://www.ssllabs.com/ssltest/index.html" site
    and also check to request URL security level then I find the difference is requested URL have to enable a weak level Cipher Suites you can see in the below image

enter image description here

Now here are my hosting server supporting Cipher Suites

enter image description here

here is called if you have control over requesting URL host server then you can sync this both server Cipher Suites. but in my case, it's not possible so I have applied the following script in Windows PowerShell on my hosting server for enabling required weak level Cipher Suites.

Enable-TlsCipherSuite -Name "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"
Enable-TlsCipherSuite -Name "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
Enable-TlsCipherSuite -Name "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
Enable-TlsCipherSuite -Name "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"
Enable-TlsCipherSuite -Name "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"
Enable-TlsCipherSuite -Name "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"
Enable-TlsCipherSuite -Name "TLS_RSA_WITH_AES_256_GCM_SHA384"
Enable-TlsCipherSuite -Name "TLS_RSA_WITH_AES_128_GCM_SHA256"
Enable-TlsCipherSuite -Name "TLS_RSA_WITH_AES_256_CBC_SHA256"
Enable-TlsCipherSuite -Name "TLS_RSA_WITH_AES_128_CBC_SHA256"
Enable-TlsCipherSuite -Name "TLS_RSA_WITH_AES_256_CBC_SHA"
Enable-TlsCipherSuite -Name "TLS_RSA_WITH_AES_256_CBC_SHA"

after applying the above script my hosting server Cipher Suites level look like

enter image description here

Then my issue resolved.

Note: server security level downgrade is not a recommended option.

Amol Shiledar
  • 367
  • 4
  • 12
1

I met the same exception "Exception calling "ExecuteQuery" with "0" argument(s): "The underlying connection was closed: An unexpected error occurred on a receive."" with powershell script block`

 #Setup Credentials to connect
        $Username="user@domain.com"  
        $Password="pwd4user"
        $securePassword = ConvertTo-SecureString $Password -AsPlainText -Force
        #$Cred = Get-Credential
        $Cred = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $securePassword)
     
        #Setup the context
        $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
        $Ctx.Credentials = $Cred
 
        #Get the Library and Its Root Folder
        $Library=$Ctx.web.Lists.GetByTitle($LibraryName)
        $Ctx.Load($Library)
        $Ctx.Load($Library.RootFolder)
        $Ctx.ExecuteQuery()` 

above code block can works on one of my pc, but on another PC it is not, after i added this line [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 at the header, but run it again I got another exception "Exception calling "ExecuteQuery" with "0" argument(s): "The partner returned a bad sign-in name or password error. For more information, see Federation Error -handling Scenarios."" i can confirm there is nothing wrong with my credentials, because it can works on one pc. then i search the exception info, i get this url: The partner returned a bad sign-in name or password error. For more information, see Federation Error-handling Scenarios.

the site figure out that the proxy may cause this exception, then i notice the proxy were different on this two PCs, so i changed the proxy on the pc which the script not works. finally the all exception were gone.

0

Before Execute query I put the statement as below and it resolved my error. Just FYI in case it will help someone.

ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; ctx.ExecuteQuery();

Rahul Patil
  • 159
  • 5
0

To expand on Bartho Bernsmann's answer, I should like to add that one can have a universal, future-proof implementation at the expense of a little reflection:

static void AllowAllSecurityPrototols()
{   int                  i, n;
    Array                types;
    SecurityProtocolType combined;

    types = Enum.GetValues( typeof( SecurityProtocolType ) ); 
    combined = ( SecurityProtocolType )types.GetValue( 0 );

    n = types.Length;
    for( i = 1; i < n; i += 1 )
    {   combined |= ( SecurityProtocolType )types.GetValue( i );  }

    ServicePointManager.SecurityProtocol = combined;
}

I invoke this method in the static constructor of the class that accesses the internet.

Anton Shepelev
  • 922
  • 9
  • 19
-1

I was working also on web scraping project and same issue found, below code applied and it worked nicely. If you are not aware about TLS versions then you can apply all below otherwise you can apply specific.

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;
Anjan Kant
  • 4,090
  • 41
  • 39