Getting SocketException (0x80004005) when logging into VPN

I was looking for a problem I ran into when using the AMQP.Net Lite library ( https://github.com/Azure/amqpnetlite ) and determined that it can be reproduced with a simple .NET Sockets client and server. My replay environment uses a client that sends simple text messages to the server based on some Microsoft samples (see below).

I noticed that after I sign up with my VPN company, no messages are sent with the following error:

SocketException: System.Net.Sockets.SocketException (0x80004005): An existing connection was forcibly closed by the remote host

I am running both client and server locally on my machine when I run into a problem.

I read about this exception and found out that one reason is because the network link went down for some reason. This makes sense, since registering with the VPN should temporarily break the connection, thereby throwing an exception. One interesting observation, however, is that this problem only occurs when hosting a server using IPv6. If I force it to use IPv4, then there is no connection loss. Is there a simple explanation for this?

I'm also wondering if there is a way to detect that the Socket is in bad condition without sending data? Are there any properties on the Socket that I can check to detect the problem and force it to reconnect? If not, what do people usually do in this situation to ensure that failed messages are counted after reconnecting?

Interestingly, with my test client, I have to send 2 messages before the exception is thrown, but no message is received by the server (see picture below).

I'm not a networking expert, so feel free if this is fundamental stuff.

Here is my client:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

public class SynchronousSocketClient
{

    public static void StartClient()
    {
        // Data buffer for incoming data.  
        byte[] bytes = new byte[1024];

        // Connect to a remote device.  
        try
        {
            // Establish the remote endpoint for the socket.  
            // This example uses port 11000 on the local computer.  
            IPHostEntry ipHostInfo = Dns.GetHostEntry(Environment.MachineName);
            IPAddress ipAddress = ipHostInfo.AddressList[0];
            IPEndPoint remoteEP = new IPEndPoint(ipAddress, 11000);

            // Create a TCP/IP  socket.  
            Socket sender = new Socket(AddressFamily.InterNetworkV6,
                SocketType.Stream, ProtocolType.Tcp);

            // Connect the socket to the remote endpoint. Catch any errors.  
            try
            {
                sender.Connect(remoteEP);

                Console.WriteLine("Socket connected to {0}",
                    sender.RemoteEndPoint.ToString());

                // Encode the data string into a byte array.  
                byte[] msg = Encoding.ASCII.GetBytes("This is a test");

                Console.WriteLine("Press any key to send a message...");
                int i = 0;

                while (true)
                {
                    Console.ReadLine();
                    // Send the data through the socket.  
                    int bytesSent = sender.Send(msg);
                    Console.WriteLine(++i + " messages sent");
                }

                // Receive the response from the remote device.  
                int bytesRec = sender.Receive(bytes);
                Console.WriteLine("Echoed test = {0}",
                    Encoding.ASCII.GetString(bytes, 0, bytesRec));

                // Release the socket.  
                sender.Shutdown(SocketShutdown.Both);
                sender.Close();

            }
            catch (ArgumentNullException ane)
            {
                Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
            }
            catch (SocketException se)
            {
                Console.WriteLine("SocketException : {0}", se.ToString());
            }
            catch (Exception e)
            {
                Console.WriteLine("Unexpected exception : {0}", e.ToString());
            }

        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }

        Console.ReadLine();
    }

    public static int Main(String[] args)
    {
        StartClient();
        return 0;
    }
}

      

Here is my server:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

public class SynchronousSocketListener
{

    // Incoming data from the client.  
    public static string data = null;

    public static void StartListening()
    {
        // Data buffer for incoming data.  
        byte[] bytes = new Byte[1024];

        // Establish the local endpoint for the socket.  
        // Dns.GetHostName returns the name of the   
        // host running the application.  
        IPEndPoint localEndPoint = new IPEndPoint(IPAddress.IPv6Any, 11000);

        // Create a TCP/IP socket.  
        Socket listener = new Socket(AddressFamily.InterNetworkV6,
            SocketType.Stream, ProtocolType.Tcp);

        // Bind the socket to the local endpoint and   
        // listen for incoming connections.  
        try
        {
            listener.Bind(localEndPoint);
            listener.Listen(10);

            // Start listening for connections.  
            while (true)
            {
                Console.WriteLine("Waiting for a connection...");
                // Program is suspended while waiting for an incoming connection.  
                Socket handler = listener.Accept();

                // An incoming connection needs to be processed.  
                while (true)
                {
                    bytes = new byte[1024];
                    int bytesRec = handler.Receive(bytes);
                    data = Encoding.ASCII.GetString(bytes, 0, bytesRec);
                    Console.WriteLine(data);
                }

                // Show the data on the console.  
                Console.WriteLine("Text received : {0}", data);

                // Echo the data back to the client.  
                byte[] msg = Encoding.ASCII.GetBytes(data);

                handler.Send(msg);
                handler.Shutdown(SocketShutdown.Both);
                handler.Close();
            }

        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }

        Console.WriteLine("\nPress ENTER to continue...");
        Console.Read();

    }

    public static int Main(String[] args)
    {
        StartListening();
        return 0;
    }
}

      

Here's a screenshot of the problem:

SocketException

+3


source to share





All Articles