# ganz ganz einfach Client/Server [Problem]



## lordnaikon (3. Nov 2006)

schönen guten tag!

ich habe ein kleines problem , mit meinem mini progrämmchen. Wenn ich mich mit dem Client auf dem Server verbinde, dann ich kann ich wunderbar nachrichten schicken. sobald ich den client mit "exit" beende .. macht der server die beine hoch.  "java.io.EOFException"  ich weiß, das es sich dabei bestimmt nicht um ein socket problem handelt .. aber ich weiß nicht so recht, wie ich dem server klar machen soll , das der client jetzt abgehauen ist.

der server soll ja weiter leben , um einem zweiten oder dritten client die möglichkeit zu geben sich anzumelden(nacheinander natürlich ich hab ja keine threads) also ich denke mal , der client ist soweit korreckt. das problem , liegt irgendwo beim server denke ich .. er kommt aus der zweiten while schleife( line!=null) nicht ohne exception raus.. bevor die bedingung falsch wird wird die exception ausgelöst.

hier der code:
client

```
import java.io.*;//Streams und Stuff
import java.net.*;//Netzwerkzeuchs

public class Client
{
	public static void main(String[] args)
	{
		// Socket, über den der Client kommuniziert
		Socket newConnection = null;
		DataOutputStream outStream = null;
		

		try
		{
			// Socket anlegen
			newConnection = new Socket("localhost", 666);

			// legen Sie hier einen neuen Socket an.
			// newConnection = ...

			// ok, wir sind connected. Mitteilung ausgeben:
			System.out.println("Connected to " + newConnection.getInetAddress() + ":" + newConnection.getPort());

			// beziehen Sie einen Outputstream, um Daten an den Server zu
			// schicken.
			outStream = new DataOutputStream(newConnection.getOutputStream());

			// Inputstrom anlegen, um Daten von der Tastatur zu lesen			
			BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

			// String zum Einlesen von der Tastatur
			String line;
			boolean run = true;
			// Client in einer Schleife laufen lassen.
			while (run)
			{
				// Zeile von der Tastatur lesen.
				line = in.readLine();

				// Abbruchkriterium testen: (Wenn "exit", dann Ende der
				// While-Schleife)
				if (line.equalsIgnoreCase("exit"))
				{
					run = false;
					//break;
				}
				// und Zeile zum Server schicken
				
				outStream.writeUTF(line);
			}// while

			// Port schließen
			outStream.close();
			newConnection.close();
		}// try

		catch (Exception e)
		{
			// wenn irgendwelche Probleme auftraten, Fehlermeldung ausgeben.
			System.err.println(e);
		}// catch
		finally
		{
			// Sicher stellen, dass der Socket zu ist - egal, was passiert ist
			try
			{
				if (newConnection == null)
				{
					newConnection.close();
				}
			}
			catch (Exception e)
			{
				System.err.print(e);
			}

			// dabei beliebige Probleme ignorieren
			// catch(IOException e2) {};
		}// finally

	}// main

}// Client
```

server:

```
import java.io.*;//Streams und so
import java.net.*;//Netzwerkzeuchs

public class Server
{
	public static void main(String[] args)
	{
		// server socket: hier lauscht der Server
		ServerSocket serverSocket = null;
		DataInputStream inStream = null;

		// dieser Socket wird neu angelegt, wenn ein Client sich meldet
		Socket newConnection = null;

		try
		{
			// Socket zum Lauschen anlegen
			serverSocket = new ServerSocket(666);

			// nun gleich bereit zum Lauschen
			System.out.println("Server listening on port " + "...");

			// server lebt für "immer":
			while (true)
			{
				// accept blockiert das Programm, bis sich ein Client meldet
				newConnection = serverSocket.accept();

				// Client hat sich gemeldet, prima.
				System.out.println("######################################################################");
				System.out.println("############### Client hat sich gemeldet #############################");
				System.out.println("######################################################################");

				// nun InputStream vom Client besorgen.
				inStream = new DataInputStream(newConnection.getInputStream());

				String line = null;
				
				do
				{
					// eine Zeile vom Client einlesen
					line = inStream.readUTF();

					// wenn die nicht null, dann auf den Schirm:
					if (line != null)
					{
						System.out.println(line);
					}
					
				}// do while
				while (line != null);
				
			}// while true
		}// try
		catch (IOException e)
		{
			System.err.println("Verbindung unterbrochen :" + e);
			System.exit(1);
		}
		finally
		{
			// auf jeden Fall sichern, dass die Verbindung zum Client beendet
			// wird/wurde
			try
			{
				newConnection.close();
			}
			catch (IOException e2)
			{
				System.out.print(e2);
			}
			
		}// finally
		
	}// main
	
}// server
```


mit freundlichen grüßen lordnaikon


----------



## SlaterB (3. Nov 2006)

du könntest dem Server eine Verabschiedungsnachricht schicken, 1 Sekunde warten, und dann die Connetion closen,
dann befindet sich der Server zumindest nicht mehr im Lesemodus beim Ende der Verbindung,

allgemein ist aber so eine Exception wohl durchaus nichts ungewöhnliches denke ich, 
dein Programm sollte also damit klarkommen, die Exception abfangen und dies ebenso als Ende der Verbindung betrachten

evtl. sogar nur einen Fehler einer einzelnen Übertragung vermuten und versuchen, die Verbindung auftrechtzuerhalten,
weiß nicht ob das vorkommt, aber muss ja auch nicht sein in einem Anfängerprogramm,

schaue dir evtl. Beispielapplikation an, wie gehen andere mit solchen Situationen um,
was wird wie abgefangen, wie werden dann die Threads eingebaut?

steht sicher in jedem Lehrbuch mindestens einmal,
oder auch bei google/ in Foren wie diesem hier nach soetwas spezifischen wie 'serverSocket.accept' suchen


----------



## Gast (11. Mai 2007)

Hallo!

Ich nehme an, Du bist Dir bewußt, dass immer nur ein Client gleichzeitig senden kann, und, dieser jeweils alle anderen wartenden Clients blockiert... - ansonsten müßtest Du Threads programmieren.

Der Server kann nur für einen einzigen Client funktionieren.

Abhilfe: Trenne den try/catch-Block für die Erzeugung des Serversockets von demjenigen für das Einlesen der Clientdaten.
Im Moment besteht der Server aufgrund des einen try/catch-Blockes eigentlich nur aus einer Sequenz anstatt einer Schleife.

lG Peter


----------

