0

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

Community
  • 1
  • 1
Ahsan Qureshi
  • 59
  • 1
  • 8

2 Answers2

1

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);
        }
    }
}
i3arnon
  • 113,022
  • 33
  • 324
  • 344
  • 1.you can use pastebin. 2. It's more of a question for codereview.Stackexchange.com. 3.you should try and explain what's wrong here so other people can contribute. – i3arnon Jan 03 '14 at 11:15
  • http://codereview.stackexchange.com/questions/38502/auto-reconnect-to-server-and-if-disconnect Here is my code please Review I3arnon – Ahsan Qureshi Jan 03 '14 at 14:57
  • It's quite a lot, but my answer stands: use TcpClient, `async-await`, move the network code out of the UI to its own class and have a background task that rebuilds the connection – i3arnon Jan 04 '14 at 02:03
  • This is .net 4.5 solution.There isn't ConnectAsync for 4.0 – Davut Gürbüz Jan 28 '15 at 14:54
  • @DavutGürbüz you can build one with BeginConnect and EndConnect. – i3arnon Jan 28 '15 at 18:09
  • @I3arnon you are right. I prefered reconnecting when `Send` operation fails because of a `SocketError` , instead of using an infinite loop. Yours is better for who wants a permanent connection. – Davut Gürbüz Jan 29 '15 at 07:53
  • TCPClient has some nasty memory leak. Even if you disposes the connection, then connection is still alive. So, if you want to do many connections, TCPClient is a bit tricky to use – magallanes Dec 09 '17 at 17:38
0

As the answer above, you should use TCP client. Do not use socket ditectly in application layer.

But even when TCP client is used and you've got a lot of properties, still comes the problem. That is because TCP/IP protocol force the port in TIME_WAIT status. That's for some reasons, which is another topic. OK, now the port you use must wait for 140 seconds during that period, you cannot use this port(which means ipend in .net).There are two ways to deal with this annoying TIME_WAIT status.

  1. Try to use UDP protocol instead of TCP/IP, cause it's Connection-oriented.
  2. Change the port number, establish another connection if you insist using TCP/IP protocols.