2

I am connecting to a remote server in C# via a socket and sending data across, upon disconnect I try to re-establish the connection by creating a new socket and reinitialising it.

This works for me when I test by pulling out the ethernet cable and reconnecting it a few mins later, but occasionally (every few hours maybe) I get the one of two exceptions while connected and cannot reconnect...

System.Net.Sockets.SocketException: An established connection was aborted by the software in your host machine

.......

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

If I restart the application everything works fine once again, so im curious as to why creating a new socket doesnt work. Am I missing an initialisation somewhere perhaps? Any ideas? I use the same method for connection each time:

public static bool OpenConnection(string siteName)
{
    bool success;
    IPEndPoint ip = new IPEndPoint(IPAddress.Parse(serverIp), Convert.ToInt16(serverRemotePort));

    try
    {
        client = null;
        client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        Console.WriteLine("Try to connect to the server ..." + ip.Address.ToString());
        client.Connect(ip);
        Console.WriteLine("Connection established");

        //Send the nameSite first
        string nameSite = EncryptString(siteName, pwd, initVector) + "*";
        byte[] dataSite = new byte[100];
        dataSite = Encoding.ASCII.GetBytes(nameSite);
        client.Send(dataSite, dataSite.Length, SocketFlags.None);
        Console.WriteLine("NameSite send");
        success = true;
    }
    catch (SocketException e)
    {
        success = false;
        Console.WriteLine("Unable to connect to the server : " + e.StackTrace);
    }

    return success;
}

I try to reconnect as follows in the catch, count is incrementing with each iteration of a while loop.

if (count % 20 == 0)
{
    try
    {
        if (OpenConnection(siteName))
            connected = true;
        EventLog.WriteEntry("Connection re-established.");
    }
    catch (SocketException socketEx)
    {
        Console.WriteLine("Reconnection failed. Storing data locally. \n\n " + socketEx);
        EventLog.WriteEntry("Reconnection failed. Storing data locally. \n\n " + socketEx);
    }
}

The constructor simply initialises the IP and Port No. Why is it that certain types of disconnect prevent me from reconnecting without a restart, any ideas?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
marked
  • 589
  • 9
  • 24
  • How long do you wait between each connection attempt? – jgauffin Aug 07 '11 at 17:31
  • @jgauffin - It depends on the frequency of saving to a database (parameter), each iteration is about 1 second at the moment, so if I set it to try to reconnect every 20 iterations as above, then approx 20 seconds. Do I need to use the Socket.Close() method to clean up perhaps? – marked Aug 07 '11 at 17:37

1 Answers1

3

Do you ever call Dispose() on client to clean it up?

Try adding the call to Dispose() before you null out the client in your OpenConnection method

client.Dispose();
client = null;

After looking at the documentation for Socket on the MSDN, the Disconnect method seems like it also might solve your problem. However, I'm not sure where in your code it should go since the question shows a portion of the logic.

Brian Dishaw
  • 5,767
  • 34
  • 49
  • There is no dispose() method, would close() be the equivalent? Its described as releasing all resources allocated to the instance. I have added that now, but the error is hard to reproduce so I might not know for hours :P – marked Aug 07 '11 at 19:10
  • Are you using this Socket class? http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.aspx The documentation shows a Dispose()... so that's strange. – Brian Dishaw Aug 07 '11 at 19:14
  • Yes, thats the one, and there is indeed a Dispose() method, you're right. Intellisense hid it from me however :P seems it is "inaccessable due to its protection level". This question indicated close should suffice I think... http://stackoverflow.com/questions/3601521/c-socket-close-should-i-still-call-dispose ...Since I am opening a connection in a method for utilisation elsewhere, not just in a single block - I needn't use 'using' right? – marked Aug 07 '11 at 19:26
  • Correct (for the using statement question). Did you take a look at the Disconnect link? It has some text that talks about closing sockets and making sure the data transfer ends cleanly. – Brian Dishaw Aug 07 '11 at 19:29
  • I did, it is helpful alright, thanks. If my connection is interupted though, it is already disconnected, no? Is there a need to call disconnect() or shutdown()? – marked Aug 07 '11 at 19:39
  • Good point. I think I might be over engineering things a bit as your issue seems to be with a socket that is dying prematurely. :) – Brian Dishaw Aug 07 '11 at 19:46
  • @marked let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/2209/discussion-between-brian-dishaw-and-marked) – Brian Dishaw Aug 07 '11 at 19:46