Search code examples
c#tcpclientreconnect

Reconnect TcpClient to Server if it crashes


I am trying to make a Steam Like friends Client ...

I can connect to a server, but how do I Reconnect, if the server crashes ... and continue reconnecting until the server starts again ...


public void ConnectToUserServer()
       {
           lb_ConnectStatus.Text = "Connecting ... ";
           lb_ClientInfo.Text = "";

           byte[] sendBytes = new byte[10025];

           UserName = tb_UserName.Text;

           //Create an instance of TcpClient. 
           IPEndPoint ipend = new IPEndPoint(IPAddress.Parse(serverName), UsersPort);


           tcpClient.Connect(ipend);

           lb_ConnectStatus.Text = "Connected ... ";
           string HostName = Dns.GetHostName().ToString();

           IPAddress[] IpInHostAddress = Dns.GetHostAddresses(HostName);

           string IPV4Address = IpInHostAddress[2].ToString(); //Default IPV4Address.


           // LocalEndPoint will return the ip address and port to which the tcp connection is accepted
           var clientIpLAN = tcpClient.Client.LocalEndPoint;

           lb_ClientInfo.Text = HostName + " " + IPV4Address;

           networkStream = tcpClient.GetStream();
           send = UserName + " : " + IPV4Address;

           sendBytes = Encoding.ASCII.GetBytes(send);
           networkStream.Write(sendBytes, 0, sendBytes.Length);

           t = new Thread(DoWork);
           t.IsBackground = true;
           t.Start();

       }

Receives List of Users from server


       public void DoWork()
       {

           byte[] bytes = new byte[1024];

           while (true)  
           { 
             int  bytesRead = networkStream.Read(bytes, 0, bytes.Length);

           }
           tcpClient.Close();
           ConnectToUserServer();

       }

Thanks inadvanced


Solution

  • Wrap any actions, like reading or writing in a Try .. Catch .. and catch any errors. Then in your catch you try to reconnect. if the reconnect is succesful, restart the operation in your try. If not, then rethrow an error and finally stop. Or retry forever.

    Theres also a popular library in .net for this, Polly.

    // Retry once
    Policy
      .Handle<SomeExceptionType>()
      .Retry()
    
    // Retry multiple times
    Policy
      .Handle<SomeExceptionType>()
      .Retry(3)
    
    // Retry multiple times, calling an action on each retry 
    // with the current exception and retry count
    Policy
        .Handle<SomeExceptionType>()
        .Retry(3, onRetry: (exception, retryCount) =>
        {
            // Add logic to be executed before each retry, such as logging
        });
    
    

    In your case, something like this:

            public void DoWork()
            {
    
                byte[] bytes = new byte[1024];
    
                int bytesRead;
                while (true)
                    try
                    {
                        bytesRead = networkStream.Read(bytes, 0, bytes.Length);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Could not get data from network stream, trying to reconnect. " + e.Message);
    
                        tcpClient.Reconnect(); // Do your reconnect here.
    
                        if (!tcpClient.isConnected)
                        {
                            Console.WriteLine("Could not reconnect, rethrowing error");
                            throw e;
                        }
    
                    }
    
    
                tcpClient.Close();
                ConnectToUserServer();
    
            }