Share via


TcpClient/SslStream - An established connection was aborted by the software in your host machine

Question

Sunday, May 7, 2017 5:50 PM

I have an SSL-connection managed with TcpClient/SslStream.

public void TcpConnect()
{
    try
    {
        long beforeConnection = this.watch.ElapsedMilliseconds;
        if (this.tcpClient != null)
        {
            this.tcpClient.Close();
            this.sslStream.Close();
        }
        //this.tcpClient = new TcpClient(this.host, this.port);
        this.tcpClient = new TcpClient("127.0.0.1", 443);
        this.tcpClient.NoDelay = true;
        this.tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, false);
        this.sslStream = new SslStream(this.tcpClient.GetStream(), false, new RemoteCertificateValidationCallback(this.ValidateServerCertificate), null);
        this.sslStream.AuthenticateAsClient(this.host);
        long msToConnect = this.watch.ElapsedMilliseconds - beforeConnection;
        this.log("( thread " + this.tableRow.ToString() + " ) Established tcp connection in " + msToConnect.ToString() + " ms");
    }
    catch (Exception exception)
    {
        this.log("[exception]  ApiThread.TcpConnection: " + exception.Message.ToString());
    }
}

Every 10 seconds I send a heartbeat-type request to keep it fresh:

try
{
    this.sslStream.Write(byteArray, 0, byteArray.Length);
}
catch (Exception exception)
{
    this.log("[exception] (thread " + this.tableRow.ToString() + ") ApiThread.PostMessage(" + _url + "): " + exception.ToString());
}

The request is an HTTP-type one.

After some period of time (it may be 30 seconds or 10 minutes) the connection is broken and I get an exception:

System.IO.IOException: Unable to write data to the transport connection: An established connection was aborted by the software in your host machine.

Well, I've been reading the web and googling for solutions. Generally people suggest:

1) To look for a firewall which breaks the connection. There is no firewall. Tested in 2 different networks.

2) To activate/deactivate KeepAlive option:

this.tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true/false);

Didn't help.

What I'm not doing is that I don't read the server response, and there definitely is one, I just don't need that response for my messages. Is that possible that by not reading the incoming messages I somehow mess up with the read-buffer (by not emptying it from time to time), hence making Windows to close the connection?

What are the other possible causes for the connection closure? It's not a random connection closure but a pattern. No connection lives for more than 10-15 minutes.

Initially I was running that code on my local computer and on the remote Windows VPS, each time connecting to the web server of interest. Also I was testing that code on my local computer connecting to the local Apache web server. No matter what I do, the connection still breaks. I suppose, there is something going on either on the .NET side or on the Windows sockets side.

All replies (3)

Sunday, May 7, 2017 6:30 PM

I disabled the SSL layer and tried it with just TcpClient. The same thing, connection breaks.

Tracing showed nothing of interest:

System.Net.Sockets Verbose: 0 : [6532] Socket#51288387::Send()

System.Net.Sockets Error: 0 : [6532] Socket#51288387::UpdateStatusAfterSocketError() - ConnectionAborted

System.Net.Sockets Error: 0 : [6532] Exception in Socket#51288387::Send - An established connection was aborted by the software in your host machine.

I was running heartbeat requests on my localhost every second via POST with Connection: Keep-Alive (also tried without) and after 2 minutes of doing so the connection broke up. So it has to be something either with NET or with Windows sockets. It's not the matter of SslStream.


Sunday, May 7, 2017 7:07 PM

I wrote a separate console application to make tests, so that there would be no interference from other things in my main app.

Here is the code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Security;
using System.Net.Sockets;
using System.Text;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;


namespace ConsoleApp1
{
    public class Cycle
    {
        public TcpClient tcpClient = null;
        public NetworkStream netStream = null;

        public void SendHeartbeat(string _token)
        {
            string strBody = _token;
            this.PostMessage("/heartbeat/index.php", strBody);
        }

        public void PostMessage(string _url, string _strBody)
        {
            string strHeader = "POST " + _url + " HTTP/1.1\n" +
                   "Content-Type: text/xml\n" +
                   "Accept: text/xml\n" +
                   "Cookie: qwe=123\n" +
                   "Host: localhost\n" +
                   "Connection: Keep-Alive\n" +
                   "Content-Length: " + _strBody.Length.ToString() + "\n\n";

            string strSend = strHeader + _strBody;
            byte[] byteArray = Encoding.ASCII.GetBytes(strSend);
            bool err = true;

            try
            {
                Console.WriteLine(_strBody);
                this.netStream.Write(byteArray, 0, byteArray.Length);
                this.netStream.Flush();
            }
            catch (Exception exception)
            {
                Console.WriteLine("[exception] " + exception.HResult.ToString());
            }
        }

        public void DoCycle()
        {
            this.tcpClient = new TcpClient("127.0.0.1", 80);
            this.tcpClient.NoDelay = true;
            this.tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
            this.netStream = this.tcpClient.GetStream();
            int i = 1;
            while (true)
            {
                this.SendHeartbeat("hb=" + i.ToString());
                i++;
                Thread.Sleep(1000);
            }

        }

    }

    public class Program
    {
        public static void Main(string[] args)
        {
            Cycle cycle = new Cycle();
            cycle.DoCycle();
        }
    }
}

Here is what I get when running it.

If I set Thread.Sleep(1000) then it could run for around 100-120 cycles (i check the delivery of the message in the php script). But if instead I pause for 10 seconds in sends successfully only the first message and then the connection breaks.

Any idea on what might be causing the connection closure?


Tuesday, May 9, 2017 7:35 AM

Hi Pingguoren,

Thank you for posting here.

For your question, I test your code and debug it step by step. When I get the exception, it shows socket error 10053.

Error 10053 : Software caused connection abort.

An established connection was aborted by the software in your host computer, possibly due to a data transmission time-out or protocol error. 

For more details, you could like to check the following links.

https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx

https://wiki.pscs.co.uk/how_to:10053

https://support.microsoft.com/en-us/help/204594/error-message-10053-software-caused-connection-to-abort

I hope this would be helpful.

Best Regards,

Wendy

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 [email protected].