Socket schliessen

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:
//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:
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.
 
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
 
Zuletzt bearbeitet:
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.
 
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
 
du solltest schon immer versuchen etwas zu empfangen, auch wenn du denkst, es kommt nix.

Code:
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:
int len;
byte[] data = new byte[1024];
while((len = in.read(data,0,data.length)) > 0)
{
 //arbeiten
}
//closed
 
Zuletzt bearbeitet:
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?
 
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
 
Hallo!

..ueber das SoTimeOut eines Sockets kannst du konfigurieren wie lange ein InputStream maximal blockieren darf.
Java:
/**
 * 
 */
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
 
Zurück