Search code examples
c#network-programmingtcptcpclient

Reconnect to the server


My Tcpclient did not disconnect properly I am using Client async.
I want to reconnect again automatic when server disconnect.
What is correct path?

This is Connection code

private void Connect_btn_Click(object sender, EventArgs e)
{
    try
    {
        if (IsConnected == false)
        {
            constatus.Text = "Connecting.....";
            newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //IPEndPoint iep = new IPEndPoint(IPAddress.Any, 20);
            IPEndPoint iep = new IPEndPoint(IPAddress.Parse(IP), Convert.ToInt16(PORT));
            newsock.BeginConnect(iep, new AsyncCallback(Connected), newsock); 
        }
        else 
        {
            MessageBox.Show("Connection is Already Connected");
        }
    }
    catch (Exception)
    {
        MessageBox.Show("Please Enter IPAddress and Port Address","Error",MessageBoxButtons.OK,MessageBoxIcon.Information);   
    }
} 

       //This is Connected Function IASYNCHRESLT interface using call back
        //Connected Function Call Back Asynch use in Connection button
  void Connected(IAsyncResult iar)
   {All Commands Inputs Send Fucntion Calling}
    {
        try
        { 
            client = (Socket)iar.AsyncState;
            client.EndConnect(iar);
            this.Invoke(new viewStatus(setValue), "Connected");
            //constatus.Text = "Connected To:" + client.RemoteEndPoint.ToString();
            client.BeginReceive(data, 0, size, SocketFlags.None, new AsyncCallback(ReceiveData), client);
            GetAllDateHide_performClick();
            
        }
        catch (SocketException)
        {
            ErrorConnecting();
        }
    }

this is disconnect code

private void ButtonDisconnect_Click(object sender, EventArgs e)
{
    try
    {
        client.Close();
        constatus.Text = "Disconnected";
    }
    catch (Exception) { }
}

and how to handle the ObjectDisposed Exception i will disconnect


Solution

  • First, I'm not sure why you're using a socket directly instead of using a TcpClient (documentation). Is there a reason? because TcpClient is cleaner.

    Second, if you're already planning for asynchrony why not use async-await?

    Lastly, I won't recommend doing network operations directly from the GUI.

    About the automatic reconnection i see 2 options.

    1. Reconnecting if an operation resulted in an error.
    2. Having a backward worker trying every once in a while to reconnect.

    You haven't showed any operations so I present my take on the second one:

    public class TcpManager
    {
        private TcpClient _tcpClient;
    
        public TcpManager()
        {
            _tcpClient = new TcpClient(AddressFamily.InterNetwork);
            Task.Run(() => ConnectAsync());
        }
    
        private async Task ConnectAsync()
        {
            while (true)
            {
                if (!_tcpClient.Connected)
                {
                    Console.WriteLine("Connecting...");
    
                    try
                    {
                        _tcpClient = new TcpClient(AddressFamily.InterNetwork);
                        await _tcpClient.ConnectAsync(IPAddress.Parse(IP), Convert.ToInt16(PORT));
                        await Task.Delay(TimeSpan.FromSeconds(5));
                    }
                    catch (SocketException e)
                    {
                        Console.WriteLine(e);
                    }
                }
                else
                {
                    Console.WriteLine("Already Connected");
                }
            }
        }
    
        private void Close()
        {
            try
            {
                _tcpClient.Close();
                _tcpClient = new TcpClient(AddressFamily.InterNetwork);
                Console.WriteLine("Disconnected");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
    }