how to check active connections in both client and server applications

I have been using a free example client server program "echo server" , I wanted to learn how to test the following conditions so I could apply them to my application.

I want my client application to continuously attempt to connect to the server until a connection is made,
if the server is not running yet, I want the client to continue to try until it is.
 
If the server dies while the client is connected, I want the client to go back into a continuous
reconnect loop until another connection is made.

I've done the first part as desired, by making a function return the Socket object and continuously
making the function call while(socket != null)

I have not been able to get the second condition of going into a reconnect state if the server dies.
I thought since I have the socket object reference I could use one of the methods provided
by the Socket class to test for an active connection and if not make the reconnect function call
mySocket.isInputShutdown( )
mySocket.isOutputShutdown( )
mySocket.isConnected( )
mySocket.isBound( )
mySocket.isClosed( )

My problem is, I start the client and it trys to connect to the server continuously and then I start the server
and all is good. I kill the server and make all of those function calls in the client looking for one of them to give me some indication that the server is dead, but all of them return inaccurate results.


mySocket.isInputShutdown( )   returns false
mySocket.isOutputShutdown( ) returns false
mySocket.isConnected( ) returns true
mySocket.isBound( ) returns true
mySocket.isClosed( ) returns false

I had the client make these function calls long after I stopped the server, because I thought maybe
there was a timeout that wasn't timed out to release resources, I checked the sockets time out
settings and there is no time out set
Finally my question, how can a client application test whether or not it is still connected to a server?
why don't any of those function calls detect that the server has died?


mitchguyAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

DrWarezzCommented:
Try this:


import java.io.*;
import java.net.*;

public class ServerPing {
  public static void main ( String [] args ) {
   
    int port = 22;  // Change me to the port to connect to the server on..
    String server = "serverName";
    Socket sock = null;
   
    for ( ;; ) {
        boolean bTemp = false;
        try {
            System.out.println( "\nConnecting ..." );
            InetAddress addr = InetAddress.getByName( server );
           
            sock = new Socket ( addr, port );
           
            System.out.print ( "\nConnection Made ... " );
        } catch (Exception e) { System.out.println( "Exception occurred" ); bTemp = true; }
            if ( !bTemp ) {
                System.out.println( "Connection lost" );
            }
            while ( sock.isConnected() ) {}
    }
  }
}

gL,
[r.D]
0
Dejan PažinHead of SW DevelopmentCommented:

There must be something else wrong here, the method mySocket.isClosed( ) will return true if you kill the server and you should be able to use that.

Maybe you should make a small example that shows where the isClosed() method returns false, when it should return true. Post the code here, and we will see where is the bug.
0
mitchguyAuthor Commented:
I added a print out in the while loop
  while ( sock.isConnected() ) {}
 
to
  while ( sock.isConnected() )
{
 System.out.println("still connected: " + sock.isConnected() );
}

ran the server, ran the client, connection was made, killed the server
the client endlessly printed
still connected: true

I'll post the server code as soon as I can
I'm running the programs on linux, not that I think that should matter
0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

mitchguyAuthor Commented:
I think the only thing I've modified in this program I found is adding print outs and the port number to 6006, there are two files

mport java.net.*;
import java.io.*;

public class KnockKnockServer {
    public static void main(String[] args) throws IOException {

        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(6006);
        } catch (IOException e) {
            System.err.println("Could not listen on port: 6006.");
            System.exit(1);
        }

        Socket clientSocket = null;
        try {
            clientSocket = serverSocket.accept();
        } catch (IOException e) {
            System.err.println("Accept failed.");
            System.exit(1);
        }

        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(
                        new InputStreamReader(
                        clientSocket.getInputStream()));
        String inputLine, outputLine;
        KnockKnockProtocol kkp = new KnockKnockProtocol();

        outputLine = kkp.processInput(null);
        out.println(outputLine);

        while ((inputLine = in.readLine()) != null) {
                  System.out.println("isBound() = " + serverSocket.isBound());
                  System.out.println("isClosed() = " + serverSocket.isClosed());
                  System.out.println("kkSocket.getSoTimeout() = " + serverSocket.getSoTimeout());
             outputLine = kkp.processInput(inputLine);
             out.println(outputLine);
             if (outputLine.equals("Bye."))
                break;
        }



        out.close();
        in.close();
        clientSocket.close();
        serverSocket.close();

                  System.out.println("isBound() = " + serverSocket.isBound());
                  System.out.println("isClosed() = " + serverSocket.isClosed());
                  System.out.println("kkSocket.getSoTimeout() = " + serverSocket.getSoTimeout());
    }
}
////////////////////////////////////////
import java.net.*;
import java.io.*;

public class KnockKnockProtocol {
    private static final int WAITING = 0;
    private static final int SENTKNOCKKNOCK = 1;
    private static final int SENTCLUE = 2;
    private static final int ANOTHER = 3;

    private static final int NUMJOKES = 5;

    private int state = WAITING;
    private int currentJoke = 0;

    private String[] clues = { "Turnip", "Little Old Lady", "Atch", "Who", "Who" };
    private String[] answers = { "Turnip the heat, it's cold in here!",
                                 "I didn't know you could yodel!",
                                 "Bless you!",
                                 "Is there an owl in here?",
                                 "Is there an echo in here?" };

    public String processInput(String theInput) {
        String theOutput = null;
      System.out.println("knock knock 6006");
        if (state == WAITING) {
            theOutput = "Knock! Knock!";
            state = SENTKNOCKKNOCK;
        } else if (state == SENTKNOCKKNOCK) {
            if (theInput.equalsIgnoreCase("Who's there?")) {
                theOutput = clues[currentJoke];
                state = SENTCLUE;
            } else {
                theOutput = "You're supposed to say \"Who's there?\"! " +
                      "Try again. Knock! Knock!";
            }
        } else if (state == SENTCLUE) {
            if (theInput.equalsIgnoreCase(clues[currentJoke] + " who?")) {
                theOutput = answers[currentJoke] + " Want another? (y/n)";
                state = ANOTHER;
            } else {
                theOutput = "You're supposed to say \"" +
                      clues[currentJoke] +
                      " who?\"" +
                      "! Try again. Knock! Knock!";
                state = SENTKNOCKKNOCK;
            }
        } else if (state == ANOTHER) {
            if (theInput.equalsIgnoreCase("y")) {
                theOutput = "Knock! Knock!";
                if (currentJoke == (NUMJOKES - 1))
                    currentJoke = 0;
                else
                    currentJoke++;
                state = SENTKNOCKKNOCK;
            } else {
                theOutput = "Bye.";
                state = WAITING;
            }
        }
        return theOutput;
    }
}

0
Dejan PažinHead of SW DevelopmentCommented:

OK. Do give both client and the server, minimized as much as possible, so we can see the problem faster.
0
Dejan PažinHead of SW DevelopmentCommented:


Please post the client also. Difficult to trace without that.
0
Dejan PažinHead of SW DevelopmentCommented:
I tried your server with my own simple client, and it still works as I expected: the server reads the first line and then exits. The client call to mySocket.isClosed() returns true.

So I really need your client.
0
Dejan PažinHead of SW DevelopmentCommented:


I think I got it. Short answer first: You can use java.net.SocketException to do what you need. Just catch the java.net.SocketException and go to reconnect phase.

This is the part on the client, where you send the data:

        OutputStreamWriter osw = new OutputStreamWriter(mySocket.getOutputStream());
        osw.write("Whatever you want to send\n");
        try
        {
          osw.flush();
        }
        catch (java.net.SocketException e)
        {
          System.out.println("Server closed. You should reconnect here");
        }

The reason why I was getting isClosed = true is because I was closing the stream with osw.close().

0
mitchguyAuthor Commented:
dejanpazin,
I was using the client given by DrWarezz's post.

I will try your recomendation first thing in the morning,
thanks
0
mitchguyAuthor Commented:
still not working for me, I've reduced my test code, here is the client and server I am trying.
when the server is stopped the client dies along with it, without generating an exception
///////////////////////CLIENT
import java.io.*;
import java.net.*;

public class ServerPing
{

   Socket createSocket(String IP, int port)
    {
      Socket newSocket = null;

      try
          {
            System.out.println("attemping to connect to server");
            newSocket = new Socket(IP, port);
          }
      catch (UnknownHostException e)
          {
            System.err.println("Don't know about host: localhost.");
          }
      catch (IOException e)
          {
            System.err.println("Couldn't get I/O for the connection to: localhost.");
          }
      return newSocket;
    }

    public static void main( String[] args)
    {
      int port = 6006;
      String server = "localhost";
      Socket mySocket = null;
      ServerPing sp = new ServerPing();
        PrintWriter out = null;
        BufferedReader in = null;
        String fromServer;
      try
          {
            while(mySocket == null)
                {
                  System.out.println("attemping to connect to server");
                  mySocket = sp.createSocket("localhost", 6006);
                }

            System.out.println("\nConnection made..");

            out = new PrintWriter(mySocket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(mySocket.getInputStream()));

            while ((fromServer = in.readLine()) != null)
                {
                  System.out.println("Server: " + fromServer + "\n");
                  out.println("Hello from client");
                  try
                      {
                        Thread.sleep(200);
                      }
                  catch(InterruptedException e)
                      {
                        System.out.println(e);
                      }
                }
            for(int i=0; i<10;i++)
                {
                  out.flush();
                  out.println("Hello from client");
                  System.out.println("should generate exception?");
                }
          }
      catch(java.net.SocketException e)
          {
            System.out.println("need to re-connect to server");
                              while(mySocket == null)
                {
                  System.out.println("attemping to re-connect to server");
                  mySocket = sp.createSocket("localhost", 6006);
                }

          }
      catch (UnknownHostException e)
          {
            System.err.println("Don't know about host: localhost.");
          }
      catch (NullPointerException e)
          {
            System.out.println("NULL POINTER exception");
          }
      catch (IOException e)
          {
            System.err.println("Couldn't get I/O for the connection to: localhost.");
            while(mySocket == null)
                {
                  System.out.println("attemping to re-connect to server");
                  mySocket = sp.createSocket("localhost", 6006);
                }
          }
    }
}


//////////////////SERVER

import java.net.*;
import java.io.*;

public class ServerTest
{
    public static void main(String[] args) throws IOException
    {

        ServerSocket serverSocket = null;
        try
          {
            serverSocket = new ServerSocket(6006);
          }
      catch (IOException e)
          {
            System.err.println("Could not listen on port: 6006.");
            System.exit(1);
          }

        Socket clientSocket = null;
        try
          {
            clientSocket = serverSocket.accept();
            if(clientSocket != null)
                {
                  System.out.println("CONNECTION ACCEPTED");
                }
          }
      catch(java.net.SocketException e)
          {
            System.out.println("SERVER ERROR1:" + e);
          }
      catch (IOException e)
          {
            System.err.println("Accept failed.");
          }

        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(
                                     new InputStreamReader(
                                                     clientSocket.getInputStream()));
        String inputLine, outputLine;
   
      out.println("Hello from Server");
      try
          {
            while ((inputLine = in.readLine()) != null)
                {
                  System.out.println("from client: " + inputLine + "\n");
                  out.println("Hello from Server");
                }
          }
      catch(java.net.SocketException e)
          {
            System.out.println("SERVER ERROR2: " + e);
          }

        out.close();
        in.close();
        clientSocket.close();
        serverSocket.close();
    }
}

0
Dejan PažinHead of SW DevelopmentCommented:
There you go. I really did need your client to see the problem. I changned your ServerPing class to use OutputStreamWriter instead of PrintWriter.

The problem is that PrintWriter doesnt throw any exceptions. That's why you have to use OutputStreamWriter. Note that I also added one line of output and one call to the flush, dont really know why it doesnt throw it in the first call. I hope this is good enough.

import java.io.*;
import java.net.*;

public class ServerPing
{

   Socket createSocket(String IP, int port)
   {
      Socket newSocket = null;

      try
      {
         System.out.println("attemping to connect to server");
         newSocket = new Socket(IP, port);
      }
      catch (UnknownHostException e)
      {
         System.err.println("Don't know about host: localhost.");
      }
      catch (IOException e)
      {
         System.err.println("Couldn't get I/O for the connection to: localhost.");
      }
      return newSocket;
   }

   public static void main(String[] args)
   {
      int port = 6006;
      String server = "localhost";
      Socket mySocket = null;
      ServerPing sp = new ServerPing();

      OutputStreamWriter osw = null;
      BufferedReader in = null;
      String fromServer;
      try
      {
         while (mySocket == null)
         {
            System.out.println("attemping to connect to server");
            mySocket = sp.createSocket("localhost", 6006);
         }

         System.out.println("\nConnection made..");

         osw = new OutputStreamWriter(mySocket.getOutputStream());
         in = new BufferedReader(new InputStreamReader(mySocket.getInputStream()));

         while ((fromServer = in.readLine()) != null)
         {
            System.out.println("Server: " + fromServer + "\n");
            osw.write("Hello from client\n");
            osw.flush();

            try
            {
               Thread.sleep(200);
            }
            catch (InterruptedException e)
            {
               System.out.println(e);
            }
         }
         for (int i = 0; i < 10; i++)
         {
            osw.write("\n");
            osw.flush();
            osw.write("Hello from client\n");            
            osw.flush(); //// This is where exception is thrown
            System.out.println("should generate exception?");
         }
      }
      catch (java.net.SocketException e)
      {
         e.printStackTrace();
         System.out.println("need to re-connect to server");
         while (mySocket == null)
         {
            System.out.println("attemping to re-connect to server");
            mySocket = sp.createSocket("localhost", 6006);
         }

      }
      catch (UnknownHostException e)
      {
         System.err.println("Don't know about host: localhost.");
      }
      catch (NullPointerException e)
      {
         System.out.println("NULL POINTER exception");
      }
      catch (IOException e)
      {
         System.err.println("Couldn't get I/O for the connection to: localhost.");
         while (mySocket == null)
         {
            System.out.println("attemping to re-connect to server");
            mySocket = sp.createSocket("localhost", 6006);
         }
      }
   }
}
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.