The following are the basic skeletons of my .net server and Java client programs:

C# server skeleton

class ServerProgram
{
    static string origClientID = string.Empty;
    static string reqClientID = string.Empty;
    static string stKey = string.Empty;
    static string stValue = string.Empty;
    static Dictionary<string, KeyValue> KeyValueDictionary;
    static Dictionary<string, ClientClass> ClientDictionary;

    static void Main(string[] args)
    {
        Console.Title = "Server";
        Console.WriteLine("Server program started on address [" + Constants.SERVER_IP +":"+Constants.PORT_NO+"]");

        KeyValueDictionary = new Dictionary<string, KeyValue>();
        ClientDictionary = new Dictionary<string, ClientClass>();

        string ipAddress = Constants.SERVER_IP;
        int portNo = Constants.PORT_NO;

        IPAddress ip = IPAddress.Parse(ipAddress);            
        TcpListener listener = new TcpListener(ip, portNo);            

        // poll for clients in a 2nd thread
        Thread thread = new Thread(delegate()
        {
            ServerProgram.PollIncomingClientConns(listener);
        });

        thread.Start();
    }

    #region catching client connections
    static void PollIncomingClientConns(TcpListener listener)
    {
        listener.Start();

        try
        {
            bool keepRunning = true;

            while (keepRunning)
            {
                ClientClass client = new ClientClass(listener);

                ClientDictionary.Add(client.ID, client);

                Thread thread = new Thread(delegate()
                {
                    ServerProgram.ReadFromClient(client);
                });
                thread.Start();
            }
        }
        catch (Exception ex)
        {
            var inner = ex.InnerException as SocketException;
            if (inner != null && inner.SocketErrorCode == SocketError.ConnectionReset)
                Console.WriteLine("Disconnected");
            else
                Console.WriteLine(ex.Message);

            listener.Stop();
        }
    } 
    #endregion     

    static void ReadFromClient(ClientClass client)
    {
       try
        {
            while (client.Tcp.Connected)
            {
                string str = client.Read();
                Console.WriteLine("[" + client.ID + "] says: " + str);

                switch(str)
                {
                    case Commands.AddKeyValue:
                        //...                        
                        break;

                    case Commands.ListKeys:
                        //...
                        break;

                    case Commands.UpdateValue: 
                        //...
                        break;

                    case Commands.Yes:                            
                        //...
                        break;
                }
            }
        }
        catch
        {
            client.Disconnect();
        }
    }
}

Java Client skeleton

public class FirstJavaClientProgramTest  
{ 
    final static String LOCAL_HOST = "127.0.0.1";
    final static int PORT_NO = 4321; 

    public static void main(String args[]) throws UnknownHostException, IOException  
    { 
        try
        {
            Consolas.WriteLine("Hit enter twice to connect to localhost...\n");

            Consolas.WriteLine("Enter server IP : ");
            String ip = Consolas.ReadLine();

            Consolas.WriteLine("Enter server port : ");
            String portStr = Consolas.ReadLine();

            int port = -99;
            if(ip.equals("\n") || ip.equals("")) 
            {
                ip = LOCAL_HOST;
            } 

            if(!ip.equals("\n") || !ip.equals(""))
            { 
                port = PORT_NO;
            }
            else 
            {
                port = Integer.parseInt(portStr);
            }

            // establish the connection 
            Socket socket = new Socket(ip, port); 

            //send the client ID
            String ID = AlphaNumRandom.randomString(5);
            Consolas.WriteLine(ID);

            BinaryWriter writer = new BinaryWriter(socket);
            writer.Write(ID);

            ReaderRunnableClass readRunnable = new ReaderRunnableClass(socket);        
            Thread readThread = new Thread(readRunnable);        
            readThread.start();

            WriterRunnableClass writeRunnable = new WriterRunnableClass(socket);        
            Thread writeThread = new Thread(writeRunnable);        
            writeThread.start();
        }
        catch(Exception ex)
        {
            Consolas.WriteLine("Failed to connect to the server!");
            //Consoles.WriteLine(ex.getMessage());
        }
    }//:~ main
}//:~ class

There is a problem with the server program.

The server program can detect a disconnected client if a client is explicitly closed by the user.

But, the server program cannot explicitly detect

  1. if the client is crashed, and/or
  2. if the network link is failed during the communication

How can I detect that?

2 Answers

0
kobak On

You should periodically send keep-alive messages to all connected clients. Check this article Detection of Half-Open (Dropped) Connections. I actually recommend you to read entire series TCP/IP .NET Sockets FAQ. Here you can check example of C# implementation in KeepAlive method.

-1
ibonetti On

I think that you´ll have to create a method, iterate over the ClientDictionary, to check if the client conections are still alive. Take a look here: Instantly detect client disconnection from server socket