# Client bekommt close vom Server nicht mit



## Niki (4. Jul 2008)

Hallo!

Ich hab folgendes Problem, ich verbinde mich mit einem Socket zu einem Server. Wenn der Server den Socket mit close schließt bekommt ich das zwar am Server mit, jedoch kann der Client weiterhin mit dem PrintWriter schreiben (keine Ahnung wohin), da er das disconnect nicht mitbekommt. Was kann ich auf client Seite machen damit ich das serverseitige disconnect mitbekomme?

Danke für Tipps!

Hier noch der ClientCode:

```
public static void main(String[] args) {
		Socket so = null;
		try {
			String connect = args.length == 1 ? args[0] : "localhost:6666";
			String[] s = connect.split(":");
			String host = s[0];
			int port = Integer.parseInt(s[1]);
			so = new Socket();
			so.connect(new InetSocketAddress(host, port));
			PrintWriter writer = new PrintWriter(so.getOutputStream());
			BufferedReader br = new BufferedReader(new InputStreamReader(
					System.in));
			String line = null;
			System.out.println(">>> ");

			while ((line = br.readLine()) != null) {
				if ("exit".equalsIgnoreCase(line))
					break;
				if (!so.isConnected()) {
					System.out.println("lost connection");
					return;
				}
				writer.println(line);
				writer.flush();
				System.out.println(">>> ");
			}
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			if (so != null && !so.isClosed())
				try {
					so.close();
				} catch (IOException e) {

				}
		}

	}
```

und hier der ServerCode (der ServerSocket wird beim Starten einer WebApp erstellt):

```
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

public class StartupListener implements ServletContextListener, Runnable {

	private static final int port = 6666;

	private ServerSocket ss = null;

	private static final Logger log = LogManager.getLogger("socketinwebapp");

	private boolean stop = false;

	private Thread thread = null;

	private static int clientCount = 0;

	private List<Socket> connectedSockets = null;

	public void contextDestroyed(ServletContextEvent arg0) {
		log.info("SocketInWebapp closing " + toString());
		synchronized (this) {
			stop = true;
			try {
				this.wait();
			} catch (InterruptedException e) {				
			}
		}
	}

	public void contextInitialized(ServletContextEvent arg0) {
		log.info("SocketInWebapp starting " + toString());
		try {
			connectedSockets = new ArrayList<Socket>();
			ss = new ServerSocket(port);
			ss.setSoTimeout(1000);
			thread = new Thread(this);
			thread.setName("ServerSocketListener");
			thread.start();
		} catch (IOException ex) {
			log.error("could not create ServerSocket", ex);
		}

	}

	public void run() {
		log.info(Thread.currentThread().getName() + " started");
		while (!stop) {
			try {
				final Socket socket = ss.accept();
				connectedSockets.add(socket);
				log.info("client connected, starting new dispatcher Thread...");
				Thread dispatcher = new Thread(new Runnable() {
					public void run() {
						log.info(Thread.currentThread().getName() + " started");
						BufferedReader reader = null;
						try {
							reader = new BufferedReader(new InputStreamReader(
									socket.getInputStream()));

							String line = null;
							while ((line = reader.readLine()) != null) {
								log.info("Message received from client: "
										+ line);
							}
							log.info("no more data receiving, client disconnected");
						} catch (SocketException ex) {
							log.info("client disconnected");
						} catch (IOException ex) {
							log
									.error(
											"an IOException occured during waiting for input",
											ex);
						} finally {
							try {
								reader.close();
								socket.close();
							} catch (IOException e) {
							}
						}
					}
				});
				dispatcher.setName("SocketDispatcher #" + ++clientCount);
				dispatcher.start();
			} catch (SocketTimeoutException ste) {
			} catch (IOException ex) {
				log.error("an IOException occured", ex);
			}
		}

		log.info("closing ServerSocket");
		if (ss != null) {
			try {
				ss.close();
				log.info("ServerSocket closed");
			} catch (IOException e) {
				log.error("could not close ServerSocket", e);
			}
		} else {
			log.info("ServerSocket not initialized");
		}

		log
				.info("closing client connections (" + connectedSockets.size()
						+ ")");
		for (Socket s : connectedSockets) {
			if(s.isClosed()){
				log.info("Socket already closed");
				continue;
			}
			try {				
				s.close();
				log.info("Socket closed");
			} catch (IOException e) {
				log.error("could not close Socket");
			}
		}
		connectedSockets.clear();
		
		synchronized(this){
			this.notify();
		}

	}
}
```


----------



## SlaterB (4. Jul 2008)

musst du das überhaupt mitbekommen?
wenn der Client nicht mehr will, dann kann er doch auch den PrintWriter closen 
(hätte aber gedacht, dass das automatisch passiert)


----------



## Niki (4. Jul 2008)

Hätte ich auch gedacht. Ich find schon dass das der Client mitbekommen sollte. Sonst glaubt er ja dass alles in Ordnung ist und arbeitet fleißig weiter. Jedoch gehen alle Aufrufe ins Nirvana


----------



## Niki (4. Jul 2008)

Ok, hab den Fehler gefunden. Man muss checkError vom PrintWriter aufrufen:

```
while ((line = br.readLine()) != null) {
	if ("exit".equalsIgnoreCase(line))
		break;
	writer.println(line);
	writer.flush();
	if (writer.checkError()) {
		System.out.println("lost connection");
		return;
	}
	System.out.println(">>> ");
}
```


----------

