tutorials.de Buch-Aktion 05/2012
ERLEDIGT
JA
ANTWORTEN
12
ZUGRIFFE
926
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    DerKleineVomSee DerKleineVomSee ist offline Mitglied Silber
    Registriert seit
    Nov 2005
    Beiträge
    70
    Hi,
    ich habe gerade folgendes Problem. Ich habe eine Server-Client Applikation geschrieben die Daten miteinander austauscht. Falls der Server die Verbindung zum Client schliesst (socket.close()), möchte ich den Socket auf der Client seite abfragen. Um die geschlossende Verbindung festzustellen habe ich schon einige Funktionen ausprobiert u.a. socket.isClosed() und socket.isConnected(). Leider wird das Verbindungsende nie erkannt. Erst wenn ich das nächste mal aus einem Stream lesen oder in den Stream schreiben will bekomme ich eine Exception.

    Hier mal ein kurzes Auszug vom Server:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    //Exceptions werden jetzt mal ignoriert
     
    private void startConnectionToClient(String ip, int timeout, String PORT)   {
     
        SocketAddress addr = new SocketAddress(ip, PORT);
        Socket socket = new Socket();
        socket.connect(addr, timeout);
        
        ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
        ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
     
     
        //tuhe irgendwas......
     
        //Schliesse jetzt doch mal die Verbindung
     
        out.close();
        in.close();
        socket.close();
     
    }//startServer

    ..und hier vom Client:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    private void waitServerConnection(String port)
     
        ServerSocket serverSocket =new ServerSocket(port);
        Socket socket = serverSocket.accept();
        ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
        ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
     
     
        //tuhe irgendwas
     
        while(true) {
     
            if(socket.isClosed())   {
                //tuhe irgendwas
            }//if
     
            else    {
                //tuhe das normale  
            }//
     
        }//while
     
    }

    Wie ihr aus dem Code sehen könnt, wartet der Client auf die Verbindung zum Server. Dann tuhen die beiden irgendwas, bis der Server die Verbindung schließt, was ich auf der Client Seite bemerken will, was aber nicht klappt.

    Ich hoffe ihr hab eine Idee.
     

  2. #2
    Avatar von teppi
    teppi teppi ist offline Mitglied Platin
    Registriert seit
    May 2004
    Ort
    Berlin
    Beiträge
    537
    Dein Serversocket ist auf der Client seite. Das ist schonmal komisch ..

    Ansonsten wäre es ja auch möglich in der Exception den Socket zu schließen ..

    Gruß Stefan
    Geändert von teppi (12.06.06 um 11:15 Uhr)
     
    :-) möp

  3. #3
    DerKleineVomSee DerKleineVomSee ist offline Mitglied Silber
    Registriert seit
    Nov 2005
    Beiträge
    70
    Die beiden Funktionen habe ich auch schon probiert, aber aus Gründen der Übersichtlichkeit weggelassen. Die beiden Funktionen bemerken leider auch nicht den geschlossenen Socket vom Server.
     

  4. #4
    Registriert seit
    Jun 2002
    Ort
    Saarbrücken (Saarland)
    Beiträge
    9.886
    Blog-Einträge
    29
     
    Java rocks!
    How to become a good Java Programmer?
    Does IT in Java and .Net
    The only valid measurement of code quality: WTFs / minute
    Blog
    Xing
    Twitter

  5. #5
    DerKleineVomSee DerKleineVomSee ist offline Mitglied Silber
    Registriert seit
    Nov 2005
    Beiträge
    70
    Den Link hatte ich mir auch schonmal angeschaut, aber leider bringt der mir nicht sehr viel. Das Probleme ist, dass ich nicht ständig Daten sende. Der Client führt eine berechnung aus, die einige Minuten dauern kann. Aus diesem Grund möchte ich in der while Schleife testen ob die Verbindung noch besteht, um so die berechnung abbrechen zu können. Durch das schliessen des Sokets auf der Server Seite weis der Client, dass der Server den Wert der Berechnung nicht mehr benötigt.

    Wenn ich mir einige Beispiele anschaue, ist es immer so das der Server auf die Verbindungen von Clients wartet und der Client dann die Verbindung herstellt. Dies ist bei mir genau anders herum. Kann es dadurch nicht funktionieren
     

  6. #6
    Freak2k Freak2k ist offline Mitglied Gold
    Registriert seit
    Apr 2005
    Beiträge
    129
    du solltest schon immer versuchen etwas zu empfangen, auch wenn du denkst, es kommt nix.

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    Object obj;
    try
    {
      while((obj = in.readObject()) != null)
      {
         //arbeite mit den daten
      }
      //verbindung geschlossen
    }
    catch(Exception e)
    {
      //verbindung geschlossen
    }

    oder du liest direct aus dem InputStream
    Code :
    1
    2
    3
    4
    5
    6
    7
    
    int len;
    byte[] data = new byte[1024];
    while((len = in.read(data,0,data.length)) > 0)
    {
     //arbeiten
    }
    //closed
    Geändert von Freak2k (13.06.06 um 13:54 Uhr)
     

  7. #7
    DerKleineVomSee DerKleineVomSee ist offline Mitglied Silber
    Registriert seit
    Nov 2005
    Beiträge
    70
    Naja, so ganz geht das ja auch nicht. Ich kann ja nur versuchen etwas zu empfangen wenn ich auch etwas gesendet wurde. Wenn ich aber nicht sende blokieren die read Methoden solange, bis etwas angekommen ist. Oder geht das irgendwie auch anders?
    Ich finde es aber auch nicht sehr elegant ständig Datenpakete senden zu müssen um eine geschlossene Verbindung zu erkennen. Gibt es den keinen anderen Weg?
     

  8. #8
    Freak2k Freak2k ist offline Mitglied Gold
    Registriert seit
    Apr 2005
    Beiträge
    129
    wieso?
    das empfangen erledigst du in einem eigenen Thread, da stoert es keinen, dass die read methode blockiert, und der thread erkennt dadurch auch, ob die Verbindung geschlossen wurde....

    Und senden kannst du nebenbei...im haupt thread
     

  9. #9
    Registriert seit
    Jun 2002
    Ort
    Saarbrücken (Saarland)
    Beiträge
    9.886
    Blog-Einträge
    29
    Hallo!

    ..ueber das SoTimeOut eines Sockets kannst du konfigurieren wie lange ein InputStream maximal blockieren darf.
    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    
    /**
     * 
     */
    package de.tutorials;
     
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
     
    /**
     * @author Tom
     * 
     */
    public class ClientServerExample {
     
        /**
         * @param args
         */
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newFixedThreadPool(2);
            executorService.execute(new Server(9888));
            executorService.execute(new Client(9888));
     
            try {
                Thread.sleep(20000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
     
            executorService.shutdown();
     
        }
     
        static class Server implements Runnable {
            ServerSocket serverSocket;
     
            public Server(int port) {
                try {
                    serverSocket = new ServerSocket(port);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
     
            public void run() {
                try {
                    Socket socket = serverSocket.accept();
                    try {
                        Thread.sleep(10000L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    socket.getOutputStream().write('a');
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
     
        static class Client implements Runnable {
     
            Socket socket;
     
            public Client(int port) {
                try {
                    socket = new Socket("localhost", port);
                    socket.setSoTimeout(5000); //InputStreams blockieren maximal fuer 5s 
                    //socket.bind(new InetSocketAddress("localhost",port));
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
     
            public void run() {
                try {
                    InputStream inputStream = socket.getInputStream();
                    System.out.println((char) inputStream.read());
     
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    Wird bei einem read(...) der TimeOut ueberschritten so bekommt man eine java.net.SocketTimeoutException. Der Socket ist danach immernoch gueltig!

    Gruss Tom
     
    Java rocks!
    How to become a good Java Programmer?
    Does IT in Java and .Net
    The only valid measurement of code quality: WTFs / minute
    Blog
    Xing
    Twitter

  10. #10
    DerKleineVomSee DerKleineVomSee ist offline Mitglied Silber
    Registriert seit
    Nov 2005
    Beiträge
    70
    stimmt....mit einem Thread kann man das gut erledigen. Da kam ich aber leider nicht drauf.
    Besten Dank.
     

  11. #11
    Registriert seit
    Jun 2002
    Ort
    Saarbrücken (Saarland)
    Beiträge
    9.886
    Blog-Einträge
    29
    Hallo!

    Ich denke die Variante mit dem TimeOut ist beser als einen zusaetzlichen Thread zu verwalten...

    Gruss Tom
     
    Java rocks!
    How to become a good Java Programmer?
    Does IT in Java and .Net
    The only valid measurement of code quality: WTFs / minute
    Blog
    Xing
    Twitter

  12. #12
    Freak2k Freak2k ist offline Mitglied Gold
    Registriert seit
    Apr 2005
    Beiträge
    129
    Zitat Zitat von Thomas Darimont
    Hallo!

    Ich denke die Variante mit dem TimeOut ist beser als einen zusaetzlichen Thread zu verwalten...

    Gruss Tom
    aso?
     

  13. #13
    DerKleineVomSee DerKleineVomSee ist offline Mitglied Silber
    Registriert seit
    Nov 2005
    Beiträge
    70
    Im Prinzip würd ich Tom schon recht geben, aber mit Blick auf meine komplette Applikation wäre das setzten von einer TimeOut Zeit nicht gut, da es an anderen Stellen des Programmes vorkommen kann, dass lange auf das lesen von Daten gewartet werden muss und hierbei nicht gesagt werden kann wie lange dies dauern kann.
     

Ähnliche Themen

  1. Socket aus anderem Thread schliessen
    Von StehtimSchilf im Forum .NET Web und Kommunikation
    Antworten: 4
    Letzter Beitrag: 25.06.10, 13:41
  2. Antworten: 2
    Letzter Beitrag: 30.01.08, 10:24
  3. Antworten: 2
    Letzter Beitrag: 29.01.08, 14:59
  4. Server Socket und Client Socket
    Von spiderman21 im Forum Netzwerke
    Antworten: 1
    Letzter Beitrag: 22.10.07, 01:48
  5. Socket schliessen
    Von MaLb im Forum Java
    Antworten: 4
    Letzter Beitrag: 29.12.06, 11:28