Link to home
Start Free TrialLog in
Avatar of tzelve
tzelve

asked on

I would like to know if the socket is alive?

I would like to know if the socket is alive "without" Blocking IO.
I know the way with the InputStream.read() method but this method making blocking IO and i wouldn't want this because i would like to read the InputStream for the other methods.

Thanks Nikos Tzelvenzis.
Avatar of LexZEUS
LexZEUS

You can use available() before trying to read() it ..

if (inpustream.available()>0)
   {
   // do whatever or read from the stream ...
   }

should work just fine :)
Above method cannot detect whether the remote socket is down or not...

This is a plain trick to detect remote socket is down or not:

public void connect() {
try
{
  Socket sock = new Socket(......);
  sock.setSoTimeout(5000);
  InputStream in = sock.getInputStream();
}
catch (Exception ex)
{
  System.out.println("Cannot connect to remote host: "+ex.toString());
  return;
}

while(true)
{
byte bt;
try {
    bt = in.read();
    }
catch (java.io.InterruptedIOException ex1)
    {
    System.out.println("remote host never send anything for 5 seconds!");
    // Thread.currentThread().sleep(100) to rest for a moment?
    continue; // try to listen again ...
    }
catch (java.io.IOException ex2)
    {
    System.out.println("remote host is down!!!");
    break; // to exit from loop,
           // and maybe.. reconnect again later?
    }
System.out.println("Receive data: "+bt);
}
} // end of method connect()


rgds,

Alex
try this:
InputStream in = socket.getInputStream();
BufferedInputStream bis = new BufferedInputStream(in);
bis.mark(1);
int r = bis.read();
bis.reset();
...
Avatar of tzelve

ASKER

Thanks i know these way but the problem is that.
The class run as thread and the run() method waitting to come data all the time.
I have some methods like GetTime() (example) which send and receive data via the Socket...the problem generate when i would like to receive data from GetTime() method because the run() method receive first the data.It's work perfect with availiable() method of InputStream Class but i can't detect when the socket dies...
I think to make with the PushbackInputStream class which have unread method() but i am thinking about this.

If you have something beter tell me.

Thanks.
Avatar of tzelve

ASKER

Thanks i know these way but the problem is that.
The class run as thread and the run() method waitting to come data all the time.
I have some methods like GetTime() (example) which send and receive data via the Socket...the problem generate when i would like to receive data from GetTime() method because the run() method receive first the data.It's work perfect with availiable() method of InputStream Class but i can't detect when the socket dies...
I think to make with the PushbackInputStream class which have unread method() but i am thinking about this.

If you have something beter tell me.

Thanks.
Ok, set the timeout to 10 when you instantiate the socket:

Socket sock = new Socket("myserver", 7777);
sock.setSoTimeout(10);

10 means 10 mili-secs, it will trigger InterruptedIOException if read() cannot retrieve any data in 10 mili-secs. So if you catch this exception, just ignore it. But if the exception is IOException, that means read() cannot retrieve data because remote server is down.

This is in your thread's run():

public void run()
{
byte timeBuffer[] = new byte[6];  
while(true)
  {
  // try to sleep for 1 seconds, so the output will be
  // the same as clock's tick
  try { sleep(1000); } catch (Exception ex) {}

  // if 1 sec already expired, now get current time
  // from server
  try { in.read(timeBuffer); } // read time from socket

  // if server never response but server is not
  // dead, then loop from beginning again
  catch (InterruptedIOException ex1) { continue; }

  // if server never response because server is dead,
  // then quit from program ...
  catch (IOException ex2) {
        System.out.println("Server is down");
        break; // to exit from loop,
        }

  // this will print current time:
  System.out.print(timeBuffer[0]+"-");
  System.out.print(timeBuffer[1]+"-");
  System.out.print(timeBuffer[2]+", ");
  System.out.print(timeBuffer[3]+":");
  System.out.print(timeBuffer[4]+":");
  System.out.print(timeBuffer[5]+"");
  }
}

Assuming if the server push byte[] like this:
byte[] bt = { 16, 1, 78, 12, 0, 0 };
this means 16 JAN 1978, at 12:00:00

Then, the client should be able to print in the loop:
16-1-78, 12:0:0

I think this code will this work fine.. :)
Avatar of tzelve

ASKER

Good way LexZEUS nut it isn't for this application.
I have the run() method which read the InputStream of the Socket and i would have another methos ex. called GetTime() which send and receive some data.If The read() in Run() method waitting (with or without timeout) will catch first the data and the other method will lose the data that assign for this.
I will try PushbackInputStream Class maybe unread() method of this Class will do that i want.
Hi tzelve,
I will repeat my suggestion:
wrap you socket input stream with a BufferedInputStream
InputStream in = socket.getInputStream();
BufferedInputStream bis = new BufferedInputStream(in);

The mark your position:
bis.mark(1);

and try to read - only to check whteher everything is OK:
int r = bis.read();

reset the the readed data:
bis.reset();

this is the unread() method that you want.
This way you wan't lose any data!
Avatar of tzelve

ASKER

Thanks Venci75 but doesn't work. My code is :



public class ClientSocket extends Thread {
   
.....


    public String GetServerTime() {
        String Answer = null;
        if (Connected) {
            SocketIsBuzy = true;                                            //Mark The Socket as buzy
            try {
                out.write(2);                                               //Send the Command Number
                out.flush();                                                //Start to send Data From Socket's Bufffer To Socket
                Answer = ReadString();                                      //Read The Received Data
            }
            catch (IOException e) {
                FireSocketError(DisconnectError);                           //Error to trasmit data (or Receive)
            }
            SocketIsBuzy = false;                                           //Unmark The Socket as buzy
        }
        return Answer;                                                      //Returned Data
    }




   public void run() {
        int CommandNumber = 0;                                              //Temporary Variable to Stora The Command Number That Received
        if (Connected == false)                                             //Send No Connected Error
            FireSocketError(NoConnectError);                                //Error to trasmit data (or Receive)
        PushbackInputStream test = new PushbackInputStream(in);
        while (Connected) {                                                 //Never Stop The Procedure until Deisconnect Socket
           TimerTask PingTask = new TimerTask() {            
            public void run() {
                 Ping();}
           };
           PingTimer.schedule(PingTask,0,1000);
            try {
                while ((in.available() == 0 ) || (SocketIsBuzy == true)){   //Wait If The Socket Is Buzy
                    sleep(100);
                }
               
                SocketIsBuzy = true;                                        //Flaged the socket as buzy
                CommandNumber = in.read();
                if (CommandNumber == 10) {                                  //If The Command Is Ping
                    out.write(10);                                          //Answer The Same
                    out.flush();                                            //Start to send Data From Socket's Bufffer To Socket
                }
                else if (CommandNumber == 11) {                             //If The Command Is GetUserName
                    SendString("petros");                                   //Answer For Test
                    out.flush();                                            //Start to send Data From Socket's Bufffer To Socket
                }
                else if (CommandNumber == 12) {                             //If The Command Is GetUserAccess
                    out.write(10);                                          //Answer For Test
                    out.flush();                                            //Start to send Data From Socket's Bufffer To Socket
                }
                else if (CommandNumber == 13) {                             //If The Command Is GetUserFullName
                    SendString("Pelopidas ntrompogianos");                  //Answer For Test
                    out.flush();                                            //Start to send Data From Socket's Bufffer To Socket
                }
                SocketIsBuzy = false;                                       //flaged the socket as not buzy
            }
            catch (IOException e){
                System.out.println("Kopike!!!");
                FireSocketDisconnect();                                     //Error to trasmit data (or Receive)
            }
            catch (InterruptedException e) {
                FireSocketError(SleepThreadError);                          //Error to trasmit data (or Receive)
            }
        }
    }
}


When i call GetServerTime the run method catch first the data if i do this with the mark.
ASKER CERTIFIED SOLUTION
Avatar of Venci75
Venci75

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
Avatar of girionis
No comment has been added lately, so it's time to clean up this TA.

I will leave a recommendation in the Cleanup topic area that this question is:

- points to Venci75

Please leave any comments here within the
next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER !

girionis
Cleanup Volunteer