5

I have a java program with Socket. I need to check if client has disconnected. I need a example how to do that. I have researched but I don't understand. So can someone make example code and explane everything.

sorry for bad English my code:

    package proov_server;

//SERVER 2
import java.io.*;
import java.net.*;

class server2 {
    InetAddress[] kasutaja_aadress = new InetAddress[1000];
    String newLine = System.getProperty("line.separator");
    int kliendiNr = 0;
    int kilene_kokku;
  server2(int port) {

    try {

      ServerSocket severi_pistik = new ServerSocket(port);
        System.out.println("Server töötab ja kuulab porti " + port + ".");


      while (true) {

        Socket pistik = severi_pistik.accept();
        kliendiNr++;

        kasutaja_aadress[kliendiNr] = pistik.getInetAddress();
        System.out.println(newLine+"Klient " + kliendiNr + " masinast "
                      + kasutaja_aadress[kliendiNr].getHostName() + " (IP:"
                      + kasutaja_aadress[kliendiNr].getHostAddress() + ")");

        // uue kliendi lõime loomine
        KliendiLoim klient = new KliendiLoim(pistik,kliendiNr);

        // kliendi lõime käivitamine
        klient.start();

      }
    }
    catch (Exception e) {
      System.out.println("Serveri erind: " + e);
    }
  }

  DataOutputStream[] väljund = new DataOutputStream[1000];
  DataInputStream[] sisend = new DataInputStream[1000];

  int klient = 0;
  int nr;
  // sisemine klass ühendusega tegelemiseks
      class KliendiLoim extends Thread {

        // kliendi pistik

      Socket pistik;
        // kliendi number


        KliendiLoim(Socket pistik2,int kliendiNr) {
          nr = kliendiNr;
          this.pistik = pistik2;

        }
        public boolean kontroll(){
            try{
                System.out.println("con "+pistik.isConnected());
                System.out.println("close "+pistik.isClosed());
                if(pistik.isConnected() &&  !pistik.isClosed()){
                    //System.out.print(con_klient);
                    return true;

                }
            }catch(NullPointerException a){
                System.out.println("Sihukest klienti pole!!!");

            }
            kliendiNr --;
            return false;

        }

        public void run() {
              try { 
                    sisend[nr] = new DataInputStream(pistik.getInputStream()); //sisend
                    väljund[nr] = new DataOutputStream(pistik.getOutputStream()); //väljund 
              }catch (Exception ea) {
                    System.out.println(" Tekkis erind: " + ea);
              }   
              while(true){
                      try{


                        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

                        System.out.print("Sisesta k2sk: ");
                        String k2sk = null;
                        k2sk = br.readLine();
                        /*
                        String command;
                        if(k2sk.indexOf(" ") < 0){
                            command = k2sk;
                        }else{
                            command = k2sk.substring(0, k2sk.indexOf(" "));
                        }
                        */
                        String[] words = k2sk.split("\\s+");
                        for (int i = 0; i < words.length; i++) {
                            words[i] = words[i].replaceAll(" ", "");
                        }
                        switch(words[0]){
                        case "suhtle":

                            if(väljund.length > klient && väljund[klient] != null)
                            {
                                väljund[klient].writeUTF("1");


                            }else{
                                väljund[klient] = null;
                                sisend[klient] = null;
                                System.out.println("Sihukest klienti pole");
                            }
                        break;
                        case "vaheta":
                            try{
                                int klinetnr = Integer.parseInt(words[1]);
                                //if(kontroll(klinetnr) ){
                                    klient = Integer.parseInt(words[1]);
                                //}
                            }
                            catch(NumberFormatException e){
                                System.out.println("See pole number!!! ");
                            }
                        break;

                        case "kliendid":
                            if(kliendiNr != 0){
                                for(int i=1;i <= kliendiNr;i++){
                                    if(kontroll()){
                                        System.out.println("Klient:"+i+" ip: " + kasutaja_aadress[i] );
                                    }else{
                                        System.out.println("Pisi");
                                        väljund[klient] = null;
                                        sisend[klient] = null;
                                    }
                                }
                                System.out.println(newLine);
                            }else{
                                System.out.println("Kiente pole");
                            }
                        break;

                        }
                      System.out.println(kliendiNr);
                    }catch(SocketException a){
                        System.out.println("Klient kadus");

                    }
                    catch(Exception e){
                         System.out.println(" Viga: " + e);
                    }

          }
        }



  }
  public static void main(String[] args) {
        new server2(4321);

  }
}
Pisikoll
  • 61
  • 1
  • 1
  • 9
  • 2
    Can you provide us with some of your code so we can help! – jsalonen Jul 26 '13 at 16:11
  • 1
    I did copy paste. I am new in java – Pisikoll Jul 26 '13 at 16:18
  • There is a lot of code, and some of the variables names are not in English. I suggest that you translate some of them, so that it could be easier to read. This is not an obligation but it could help. – Marc-Andre Jul 26 '13 at 16:36
  • There is some methods in the [Socket Documentation](http://docs.oracle.com/javase/7/docs/api/java/net/Socket.html) that look promising to me. Like isClosed and isConnected. Maybe that could be a start ? – Marc-Andre Jul 26 '13 at 18:09
  • @Marc-Andre No. They tell you the status of the socket, not the connection. – user207421 Jul 26 '13 at 19:16
  • @EJP It was only a proposition, thanks for pointing that out. – Marc-Andre Jul 26 '13 at 19:18

2 Answers2

13

If the client has disconnected properly:

  • read() will return -1
  • readLine() returns null
  • readXXX() for any other X throws EOFException.

The only really reliable way to detect a lost TCP connection is to write to it. Eventually this will throw an IOException: connection reset, but it takes at least two writes due to buffering.

user207421
  • 305,947
  • 44
  • 307
  • 483
3

A related thread on Stackoverflow here along with the solution. Basically, the solution says that the best way to detect a client-server disconnect is to attempt to read from the socket. If the read is successfully, then the connection is active.If an exception is thrown during the read there is no connection between the client and the server. Alternatively it may happen that the socket is configured with a timeout value for the read operation to complete. In case, this timeout is exceeded a socket timeout exception will be thrown which can be considered as either the client is disconnected or the network is down.

The post also talks about using the isReachable method - refer InetAddress documentation. However, this method only tells us whether a remote host is reachable or not. This may just one of the reasons for the client to disconnect from the server. You wont be able to detect disconnection due to client crash or termination using this technique.

Community
  • 1
  • 1
Prahalad Deshpande
  • 4,709
  • 1
  • 20
  • 22
  • I'm wondering if the socket is connected but there is nothing to read, what would happen? – Marc-Andre Jul 26 '13 at 18:08
  • 1
    I made a minor correction to the answer - in case, the socket is connected and there is nothing to read, then there is no exception thrown and the program just continues executing the next lines. It is only when a socket is disconnected will a read from the socket result in an exception. – Prahalad Deshpande Jul 26 '13 at 18:19
  • 1
    That's not correct. If you've set a read timeout in blocking mode and there is no data you will get a SocketTimeoutException. It's up to you to decide whether that means the peer is inactive or the network is down. The answers in the thread you cited are very low quality. – user207421 Jul 26 '13 at 19:13
  • @EJP Thank you for your comment - I incorporated your note into my answer.The accepted answer in the thread posted above seems to be a reasonable one to me. However, do update this thread with any more simpler techniques available to solve this problem – Prahalad Deshpande Jul 26 '13 at 19:29
  • Loss of reachability doesn't cause a peer to disconnect. It may break the connection, but that isn't the same thing. Nor is a timeout exception the same as a peer disconnect. The best way to detect a client disconnect is to read and get end of stream, but the best way to detect a broken connection is to *write* to it. Again, these are not the same thing. And the question is a about peer disconnections, not about broken connections, – user207421 Jul 16 '15 at 10:03