System.Net.Sockets.SocketException

The exception that is thrown when a socket error occurs.

Minimum version: >= 1.1 >= Core 1.0

Statistics

9
elmah.io logo 7
8

How to handle it

try
{

}
catch (System.Net.Sockets.SocketException e)
{

}
try
{

}
catch (System.Net.Sockets.SocketException e) when (e.Message.Contains("something"))
{

}
try
{

}
catch (System.Net.Sockets.SocketException e) when (LogException(e))
{

}

private static bool LogException(Exception e)
{
    logger.LogError(...);
    return false;
}

How to avoid it

We haven't written anything about avoiding this exception yet. Got a good tip on how to avoid throwing System.Net.Sockets.SocketException? Feel free to reach out through the support widget in the lower right corner with your suggestions.

Links

YouTube videos

Possible fixes from StackOverflow

On Windows Vista (and Windows 7), Dns.GetHostEntry also returns IPv6 addresses. In your case, the IPv6 address (::1) is first in the list.

You cannot connect to an IPv6 (InterNetworkV6) address with an IPv4 (InterNetwork) socket.

Change your code to create the socket to use the address family of the specified IP address:

Socket serverSocket =
    new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                        ↑

Note: There's a shortcut to obtain the IP address of localhost: You can simply use IPAddress.Loopback (127.0.0.1) or IPAddress.IPv6Loopback (::1).

An established connection was aborted by the software in your host machine

That is a boiler-plate error message, it comes out of Windows. The underlying error code is WSAECONNABORTED. Which really doesn't mean more than "connection was aborted". You have to be a bit careful about the "your host machine" part of the phrase. In the vast majority of Windows application programs, it is indeed the host that the desktop app is connected to that aborted the connection. Usually a server somewhere else.

The roles are reversed however when you implement your own server. Now you need to read the error message as "aborted by the application at the other end of the wire". Which is of course not uncommon when you implement a server, client programs that use your server are not unlikely to abort a connection for whatever reason. It can mean that a fire-wall or a proxy terminated the connection but that's not very likely since they typically would not allow the connection to be established in the first place.

You don't really know why a connection was aborted unless you have insight what is going on at the other end of the wire. That's of course hard to come by. If your server is reachable through the Internet then don't discount the possibility that you are being probed by a port scanner. Or your customers, looking for a game cheat.

Is it possible that the serverSocket is being closed from another thread? That will cause this exception.

You just need to keep digging. The exception "The response ended prematurely" isn't the root cause. Keep digging into the inner exceptions until you find the last one. You'll find this:

System.IO.IOException: Authentication failed because the remote party has closed the transport stream.

So it's not about your code. It seems the server you're hitting either can't handle the load, or is intentionally dropping your requests because you're hitting it too hard.

we resolved this problem with 2 code changes:

  1. Dispose of the httpResponseMessage and just work with a simple DTO

    using (var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage))
    {
        return await CreateDto(httpResponseMessage);
    }
    
  2. Downgrade the version of HTTP to v1.0

    var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, new Uri(url))
    {
        Version = HttpVersion.Version10,
        Content = httpContent
    };
    
    await client.SendAsync(httpRequestMessage);
    

which has the effect of adding this Http header

Connection: close 

rather than this

Connection: keep-alive