Link to home
Start Free TrialLog in
Avatar of mitchguy
mitchguy

asked on

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?


Avatar of DrWarezz
DrWarezz

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]
Avatar of Dejan Pažin

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.
Avatar of mitchguy

ASKER

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
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;
    }
}


OK. Do give both client and the server, minimized as much as possible, so we can see the problem faster.


Please post the client also. Difficult to trace without that.
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.


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().

dejanpazin,
I was using the client given by DrWarezz's post.

I will try your recomendation first thing in the morning,
thanks
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();
    }
}

ASKER CERTIFIED SOLUTION
Avatar of Dejan Pažin
Dejan Pažin
Flag of Austria image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial