164

I have a server app and sometimes, when the client tries to connect, I get the following error:

enter image description here

NOTE: the "couldn't get stream from client or login failed" is a text that's added by me in catch statement

and the line at which it stops ( sThread : line 96 ) is :

tcpClient = (TcpClient)client;
clientStream = tcpClient.GetStream();
sr = new StreamReader(clientStream);
sw = new StreamWriter(clientStream);

// line 96:                 
a = sr.ReadLine();

What may be causing this problem? Note that it doesn't happen all the time

Luke Girvin
  • 13,221
  • 9
  • 64
  • 84
Alex
  • 10,869
  • 28
  • 93
  • 165
  • 1
    ALL THIS MEANS is that you can just upgrade your Framework to something like 4.7.2 and it will probably work without any further issues. It worked for me. It upgrades the security protocols used for transport level communication. – pianocomposer Jan 29 '21 at 16:10

28 Answers28

248

I received this error when calling a web-service. The issue was also related to transport level security. I could call the web-service through a website project, but when reusing the same code in a test project I would get a WebException that contained this message. Adding the following line before making the call resolved the issue:

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

Edit

System.Net.ServicePointManager.SecurityProtocol - This property selects the version of the Secure Sockets Layer (SSL) or Transport Layer Security (TLS) protocol to use for new connections that use the Secure Hypertext Transfer Protocol (HTTPS) scheme only; existing connections are not changed.

I believe the SecurityProtocol configuration is important during the TLS handshake when selecting the protocol version.

TLS handshake - This protocol is used to exchange all the information required by both sides for the exchange of the actual application data by TLS.

ClientHello - A client sends a ClientHello message specifying the highest TLS protocol version it supports ...

ServerHello - The server responds with a ServerHello message, containing the chosen protocol version ... The chosen protocol version should be the highest that both the client and server support. For example, if the client supports TLS version 1.1 and the server supports version 1.2, version 1.1 should be selected; version 1.2 should not be selected.

Hans Vonn
  • 3,949
  • 3
  • 21
  • 15
  • 11
    Do we know more about how/why this works? I've been struggling with a PostAsync call and this does appear to fix my error, too. Glad it worked, but I'd also like to know why. – Kevin Matlock Aug 17 '17 at 15:57
  • 3
    Remember that this MUST come before you create the request. Credit to - https://stackoverflow.com/a/57377861/1572632 – Reahreic Feb 24 '21 at 13:00
  • It is not clear if he is using http or https. If he is using http, then we can ignore all the answers with TLS. – jk Registraties Mar 30 '23 at 13:14
106

This error usually means that the target machine is running, but the service that you're trying to connect to is not available. (Either it stopped, crashed, or is busy with another request.)

In English: The connection to the machine (remote host/server/PC that the service runs at) was made but since the service was not available on that machine, the machine didn't know what to do with the request.

If the connection to the machine was not available, you'd see a different error. I forget what it is, but it's along the lines of "Service Unreachable" or "Unavailable".

Edit - added

It IS possible that this is being caused by a firewall blocking the port, but given that you say it's intermittent ("sometimes when the client tries to connect"), that's very unlikely. I didn't include that originally because I had ruled it out mentally before replying.

David
  • 72,686
  • 18
  • 132
  • 173
  • 2
    the thing is that when i start the server there are some like 50 client connecting to my server . I've implemented kind of a wait signal when accepting a client .. something like while (Program.waitToFinishLoginAtClient == true && ajutor < 30) { Thread.Sleep(300); ajutor++; } client = this.tcpListener.AcceptTcpClient(); Program.waitToFinishLoginAtClient = true; ........... and Program.waitToFinishAtClient gets modified in the thread that contains the client – Alex Mar 24 '11 at 14:59
  • 1
    could this "wait" be the problem ? – Alex Mar 24 '11 at 15:02
  • 2
    I think the Wait is the problem. I don't know enough of your code to be sure, but that sure sounds likely. Just curious as to whether you built your own service the "hard way" or if you're using WCF or even Remoting for this... – David Mar 24 '11 at 15:07
  • 1
    Based on the little nit of code here, it looks to me like the "wait" problem could be avoided if it was inside a separate thread for each conneciton. Just in case that guess is right, here's an example of a multi-threaded TCP Service with multi-threading that may help you: http://www.switchonthecode.com/tutorials/csharp-tutorial-simple-threaded-tcp-server – David Mar 24 '11 at 15:10
  • 1
    my existing server is made exactly like the example in the tutorial .. except the wait . The thing is that it was working fine till recently .. – Alex Mar 24 '11 at 20:49
  • 1
    OK. I still think it'ds the wait functionality. It's likely blocking the socket. This type of issue is why I usually go with web services when possible as opposed to using TCP sockets. IIS already handles the threads and blocking far better than I can code. – David Mar 24 '11 at 20:50
  • 1
    This might occur when you DOS a slow web server or service. – ˈvɔlə Feb 27 '19 at 21:55
41

My specific case scenario was that the Azure app service had the minimum TLS version changed to 1.2

I don't know if that's the default from now on, but changing it back to 1.0 made it work.

You can access the setting inside "SSL Settings".

Hugo Hilário
  • 2,848
  • 2
  • 27
  • 43
  • 1
    I had this issue for a new powershell Azure function, but changing it to TLS1.0 doesn't help. Any reason why this i happening? – Head and toes Feb 11 '21 at 12:16
  • 1
    This isn't a great solution, what does one do if TLS is set to 1.2 on the server and it's forbidden to change it. (No access, no Admin, 100 other stakeholders, etc...) – Reahreic Feb 24 '21 at 12:55
  • 1
    @Reahreic Update your app to use 1.2 – TylerH Aug 02 '22 at 21:04
24

According to "Hans Vonn" replies.

Adding the following line before making the call resolved the issue:

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

After adding Security protocol and working fine but I have to add before every API call which is not healthy. I just upgrade .net framework version at least 4.6 and working as expected do not require to adding before every API call.

Simas Joneliunas
  • 2,890
  • 20
  • 28
  • 35
Mahi
  • 1,019
  • 9
  • 19
  • 1
    Remember that this MUST come before you create the request. Credit to - https://stackoverflow.com/a/57377861/1572632 – Reahreic Feb 24 '21 at 13:00
19

Not sure which of the fixes in these blog posts helped, but one of them sorted this issue for me ...

http://briancaos.wordpress.com/2012/07/06/unable-to-read-data-from-the-transport-connection-the-connection-was-closed/

The trick that helped me was to quit using a WebRequest and use a HttpWebRequest instead. The HttpWebRequest allows me to play with 3 important settings:

and

http://briancaos.wordpress.com/2012/06/15/an-existing-connection-was-forcibly-closed-by-the-remote-host/

  • STEP 1: Disable KeepAlive
  • STEP 2: Set ProtocolVersion to Version10
  • STEP 3: Limiting the number of service points
SteveC
  • 15,808
  • 23
  • 102
  • 173
  • 1
    I should add that I also had to add this code to the Reference.cs for the web service that was having that behavior. protected override System.Net.WebRequest GetWebRequest(Uri uri) { System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest)base.GetWebRequest(uri); webRequest.KeepAlive = false; return webRequest; } – drzounds Apr 21 '16 at 14:56
18

For those who may find this later, after .NET version 4.6, I was running into this problem as well.

Make sure that you check your web.config file for the following lines:

<compilation debug="true" targetFramework="4.5">
...
<httpRuntime targetFramework="4.5" />

If you are running 4.6.x or a higher version of .NET on the server, make sure you adjust these targetFramework values to match the version of the framework on your server. If your versions read less than 4.6.x, then I would recommend you upgrade .NET and use the newer version unless your code is dependent on an older version (which, in that case, you should consider updating it).

I changed the targetFrameworks to 4.7.2 and the problem disappeared:

<compilation debug="true" targetFramework="4.7.2">
...
<httpRuntime targetFramework="4.7.2" />

The newer frameworks sort this issue out by using the best protocol available and blocking insecure or obsolete ones. If the remote service you are trying to connect to or call is giving this error, it could be that they don't support the old protocols anymore.

Zachary Weber
  • 455
  • 3
  • 15
13

Calls to HTTPS services from one of our servers were also throwing the "Unable to read data from the transport connection : An existing connection was forcibly closed" exception. HTTP service, though, worked fine. Used Wireshark to see that it was a TLS handshake Failure. Ended up being that the cipher suite on the server needed to be updated.

Jobrocol
  • 856
  • 10
  • 12
6

This solved my problem. I added this line before the request is made:

System.Net.ServicePointManager.Expect100Continue = false;

It seemed there were a proxy in the way of the server that not supported 100-continue behavior.

Mahdi Ataollahi
  • 4,544
  • 4
  • 30
  • 38
5

This won't help for intermittent issues, but may be useful for other people with a similar problem.

I had cloned a VM and started it up on a different network with a new IP address but not changed the bindings in IIS. Fiddler was showing me "Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host" and IE was telling me "Turn on TLS 1.0, TLS 1.1, and TLS 1.2 in Advanced settings". Changing the binding to the new IP address solved it for me.

Jon.Mozley
  • 445
  • 1
  • 6
  • 12
4

For some reason, the connection to the server was lost. It could be that the server explicitly closed the connection, or a bug on the server caused it to be closed unexpectedly. Or something between the client and the server (a switch or router) dropped the connection.

It might be server code that caused the problem, and it might not be. If you have access to the server code, you can put some debugging in there to tell you when client connections are closed. That might give you some indication of when and why connections are being dropped.

On the client, you have to write your code to take into account the possibility of the server failing at any time. That's just the way it is: network connections are inherently unreliable.

Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
4
  • I was sending the HttpWebRequest from Console App, and UserAgent was null by (default), so setting UserAgent worked along with setting SecurityProtocol.
  • Should set SecurityProtocol before creating HttpWebRequest.

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

HttpWebRequest req = (HttpWebRequest)WebRequest.Create("yourpostURL");
req.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36";
Himalaya Garg
  • 1,525
  • 18
  • 23
3

The webrequest user agent is null by default. Just google "block empty user agent" and you'll find a strong desire of many web server admins to do just that.

Sending my request with request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0"; fixed the issue.

TylerH
  • 20,799
  • 66
  • 75
  • 101
ExternalUse
  • 2,053
  • 2
  • 25
  • 37
2

I get that problem in the past. I'm using PostgreSQL and when I run my program, sometimes it connects and sometimes it throws an error like that.

When I experiment with my code, I put my Connection code at the very first line below the public Form. Here is an example:

BEFORE:

    public Form1()
        {
        //HERE LIES SOME CODES FOR RESIZING MY CONTROLS DURING RUNTIME
        //CODE
        //CODE AGAIN
        //ANOTHER CODE
        //CODE NA NAMAN
        //CODE PA RIN!





        //Connect to Database to generate auto number
        NpgsqlConnection iConnect = new NpgsqlConnection("Server=localhost;Port=5432;User ID=postgres;Password=pass;Database=DB");
        iConnect.Open();
        NpgsqlCommand iQuery = new NpgsqlCommand("Select * from table1", iConnect);
        NpgsqlDataReader iRead = iQuery.ExecuteReader();
        NpgsqlDataAdapter iAdapter = new NpgsqlDataAdapter(iQuery);

        DataSet iDataSet = new DataSet();
        iAdapter.Fill(iDataSet, "ID");

        MessageBox.Show(iDataSet.Tables["ID"].Rows.Count.ToString());
        }

NOW:

    public Form1()
        {
        //Connect to Database to generate auto number
        NpgsqlConnection iConnect = new NpgsqlConnection("Server=localhost;Port=5432;User ID=postgres;Password=pass;Database=DB");
        iConnect.Open();
        NpgsqlCommand iQuery = new NpgsqlCommand("Select * from table1", iConnect);
        NpgsqlDataReader iRead = iQuery.ExecuteReader();
        NpgsqlDataAdapter iAdapter = new NpgsqlDataAdapter(iQuery);

        DataSet iDataSet = new DataSet();
        iAdapter.Fill(iDataSet, "ID");

        MessageBox.Show(iDataSet.Tables["ID"].Rows.Count.ToString());





        //HERE LIES SOME CODES FOR RESIZING MY CONTROLS DURING RUNTIME
        //CODE
        //CODE AGAIN
        //ANOTHER CODE
        //CODE NA NAMAN
        //CODE PA RIN!

        }

I think that the program must read first the connection before doing anything, I don't know, correct me if I'm wrong. But according to my research, it's not a code problem - it was actually from the machine itself.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Curbside Coder
  • 291
  • 3
  • 15
1
System.Net.ServicePointManager.Expect100Continue = false;

This issue sometime occurs due the reason of proxy server implemented on web server. To bypass the proxy server by putting this line before calling the send service.

Tahir Alvi
  • 896
  • 2
  • 14
  • 44
1

We had a very similar issue whereby a client's website was trying to connect to our Web API service and getting that same message. This started happening completely out of the blue when there had been no code changes or Windows updates on the server where IIS was running.

In our case it turned out that the calling website was using a version of .Net that only supported TLS 1.0 and for some reason the server where our IIS was running stopped appeared to have stopped accepting TLS 1.0 calls. To diagnose that we had to explicitly enable TLS via the registry on the IIS's server and then restart that server. These are the reg keys:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.0\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.0\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.1\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.1\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.2\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.2\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

If that doesn't do it, you could also experiment with adding the entry for SSL 2.0:


    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client]
    "DisabledByDefault"=dword:00000000
    "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server]
    "DisabledByDefault"=dword:00000000
    "Enabled"=dword:00000001

My answer to another question here has this powershell script that we used to add the entries:

NOTE: Enabling old security protocols is not a good idea, the right answer in our case was to get the client website to update it's code to use TLS 1.2, but the registry entries above can help diagnose the issue in the first place.

tomRedox
  • 28,092
  • 24
  • 117
  • 154
1

The reason this was happening to me was I had a recursive dependency in my DI provider. In my case I had:

services.AddScoped(provider => new CfDbContext(builder.Options));
services.AddScoped(provider => provider.GetService<CfDbContext>());

Fix was to just remove the second scoped service registration

services.AddScoped(provider => new CfDbContext(builder.Options));
Madison Haynie
  • 448
  • 4
  • 13
1

Had a similar problem and was getting the following errors depending on what app I used and if we bypassed the firewall / load balancer or not:

HTTPS handshake to [blah] (for #136) failed. System.IO.IOException Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host

and

ReadResponse() failed: The server did not return a complete response for this request. Server returned 0 bytes.

The problem turned out to be that the SSL Server Certificate got missed and wasn't installed on a couple servers.

deadlydog
  • 22,611
  • 14
  • 112
  • 118
1

For me, It was an issue where in the IIS binding it had the IP address of the web server. I changed it to use all unassigned IPs and my application started to work.

1

I experienced the error with python clr running mdx query to Microsoft analytic services using adomd

I solved it with help of Hans Vonn and here is the python version:

clr.AddReference("System.Net")
from System.Net import ServicePointManager, SecurityProtocolType 
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls
Ahmed Ali
  • 1,908
  • 14
  • 28
1

I received this error simply because I was attempting to make an http connection to an https-only server. Changing the request protocol in the URI from http to https thus resolved it.

david.barkhuizen
  • 5,239
  • 4
  • 36
  • 38
1

This is how I solved the issue:

                int i = 0;
                while (stream.DataAvailable == true)
                {
                    bytes[i] = ((byte)stream.ReadByte());
                    i++;
                }

                data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
                Console.WriteLine("Received: {0}", data);
  • 2
    This code has redundant boolean checking. while (stream.DataAvailable == true) You only need the following code. Checking if something is true so that it can be true is just redundant. while (stream.DataAvailable) – Nathan Werry Aug 16 '21 at 12:58
0

I had a Third Party application (Fiddler) running to try and see the requests being sent. Closing this application fixed it for me

Johan Aspeling
  • 765
  • 1
  • 13
  • 38
0

If you have a https certificate on the domain, make sure you have the https binding to the domain name in IIS. In IIS -> Select your domain -> Click on Bindings Site Bindings Window opens up. Add a binding for https.

0

Try checking if you can establish handshake in the first place. I had this issue before when uploading a file and I only figured out that the issue was the nonexistent route when I removed the upload and checked if it can login given the parameters.

Raffy
  • 515
  • 1
  • 8
  • 12
0

Another option would be to check the error code generated using try-catch block and first catching a WebException.

In my case, the error code was "SendFailure" because of certificate issue on HTTPS url, once I hit HTTP, that got resolved.

https://learn.microsoft.com/en-us/dotnet/api/system.net.webexceptionstatus?redirectedfrom=MSDN&view=netframework-4.8

0

This problem occurring when the Service is Unavailable within the proxy server. We can bypass the proxy server. Before start, the service, apply this code line.

System.Net.ServicePointManager.Expect100Continue = false;

Further details

Chanuka
  • 127
  • 1
  • 4
0

Insufficient listener buffer size should be taken into consideration. Messages longer than buffer size also triggers OP excetion

On the following sample, if we reduce maxBufferSize from 1024 to just 10 and send a message of 11 bytes, we also get Unable to read data from the transport connection : An existing connection was forcibly closed by the remote host is raised exception.

internal class MyTcpListener
{
    static void Main(string[] args)
    {

        // Set the TcpListener on port 13000.
        IPAddress serverAddress = IPAddress.Parse("127.0.0.1");
        int serverPort = 13000;
        int maxBufferSize = 1024;

        launchTcpListener(serverAddress, serverPort, maxBufferSize);

        Console.WriteLine("\nHit enter to continue...");
        Console.Read();

    }

    // https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcplistener?view=net-7.0
    private static void launchTcpListener(IPAddress serverAddress, int serverPort, int maxBufferSize)
    {
        System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

        TcpListener server = null;

        try
        {

            // TcpListener server = new TcpListener(port);
            server = new TcpListener(serverAddress, serverPort);

            // Start listening for client requests.
            server.Start();

            // Buffer for reading data
            Byte[] bytes = new Byte[maxBufferSize];
            String data = null;

            // Enter the listening loop.
            while (true)
            {
                Console.WriteLine("Listening at {0}:{1}", serverAddress, serverPort);

                // Perform a blocking call to accept requests.
                // You could also use server.AcceptSocket() here.
                using (TcpClient client = server.AcceptTcpClient())
                {

                    Console.WriteLine("Connected!");

                    data = null;

                    // Get a stream object for reading and writing
                    NetworkStream stream = client.GetStream();

                    int receivedBytes;

                    // Loop to receive all the data sent by the client.
                    while ((receivedBytes = stream.Read(bytes, 0, bytes.Length)) != 0)
                    {

                        // Translate data bytes to a ASCII string.
                        data = System.Text.Encoding.UTF8.GetString(bytes, 0, receivedBytes);

                        string currentTime = DateTime.Now.ToString();
                        Console.WriteLine("At {0} received: {1}", currentTime, data);

                        // Processamento de dados


                        // Embora seja facultativo, mas deve enviar-se feedback quanto à validade dos pedidos
                        // Nesta amostra isto a devolver os dados recebidos
                        byte[] responseData = System.Text.Encoding.UTF8.GetBytes(data);
                        stream.Write(responseData, 0, responseData.Length);
                        Console.WriteLine("Server response: {0}", data);
                    }

                }

            }
        }
        catch (SocketException e)
        {
            Console.WriteLine("SocketException: {0}", e);
        }
        finally
        {
            server?.Stop();
        }
    }
}
Julio Nobre
  • 4,196
  • 3
  • 46
  • 49
  • How to check this or how did you add higher buffer size ? – Sumitiscreative Aug 29 '23 at 08:11
  • @Sumitiscreative, I have updated my answer, making clear that I was referring to tcp listener, and added a listener code sample. Please, let know if there further doubts about my answer – Julio Nobre Aug 30 '23 at 11:04
-3

In my case I resolved this problem setting a correct API's url in my application.

It was an error connection between the application and API.