# Thread Frage



## ven000m (4. Apr 2007)

Hallo,

ich habe mal eine Frage bezügl. Threads.

Ich gebe in der Skeleton Klasse einen Thread ab, wenn wenn eine Verbindung herein kommt, soweit so gut. Wenn ich dann aber in der Thread Klasse die Verbindung annehmen will fliegt mir alles um die Ohren.

Gruß

*ClockSkeleton (Server):*


```
public class ClockSkeleton 
{

	public static void main (String args[]) throws IOException
	{
			

		Socket talkSocket;
		
		try {			
				
			while(true)
			{
				ServerSocket listenSocket = new ServerSocket(4711);
				talkSocket = listenSocket.accept();
					
				// Kommunikation an einen nebenläufigen Thread abgeben
				ServerThread t = new ServerThread(talkSocket); 
				t.start();						
			}			
		
		}
		catch (IOException e) {e.printStackTrace();}
		//catch (IllegalCmdException e) {e.printStackTrace();}
		//catch (InterruptedException e) {e.printStackTrace();}
		
  	}
}
```



*ServerThread:*



```
package vsy.clockdemo.server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;


public class ServerThread extends Thread { 
	private Socket talkSocket; 
	
	public ServerThread(Socket talkSocket) 
	{ 
		this.talkSocket = talkSocket; 		
	}
	
	public void run()
	{
		//Socket talkSocket;
		BufferedReader fromClient;
		OutputStreamWriter toClient;
		String stringToConvert;
		
		String zeit="";
		
		while(true)
		{			
		try{	
					
			Clock handler = new Clock();
			
			fromClient = new BufferedReader(new InputStreamReader(talkSocket.getInputStream(),"Cp1252"));
			toClient   = new OutputStreamWriter(talkSocket.getOutputStream(),"Cp1252");			
			stringToConvert= fromClient.readLine();	
			
			
			if(stringToConvert.charAt(0)=='s')
			{
				handler.start();
				toClient.write("Clock Timer gestartet.");
				System.out.println("Client drückt 'S'.");					
		    }
			
			if(stringToConvert.charAt(0)=='g')
			{
				toClient.write("Clock steht bei: "+handler.getTime()+"ms");					
				System.out.println("Client drückt 'G'.");		
				
		    }
			
			if(stringToConvert.charAt(0)=='r')
			{
				handler.reset();
				toClient.write("Clock wurde resettet.");
				System.out.println("Client drückt 'R'.");
		    }
			
			if(stringToConvert.charAt(0)=='h')
			{
				zeit=""+handler.halt();
				toClient.write("Clock wurde gestoppt bei: " +zeit+"ms");
				zeit="";
				System.out.println("Client drückt 'h'.");					
		    }
			
			if(stringToConvert.charAt(0)=='c')
			{
				handler.conTinue();
				toClient.write("Clock wird fortgesetzt bei "+handler.getTime()+" ms.");
				toClient.flush();
				System.out.println("Client drückt 'c'.");
									
		    }
			
			if(stringToConvert.charAt(0)=='e')
			{
				
				toClient.write("Clock wurde beendet.");
				toClient.flush();
				System.out.println("Client hat Uhr beendet.");
				handler.exit();
									
		    }
			
			if(stringToConvert.charAt(0)=='w')
			{
				int laenge=stringToConvert.length();					
				stringToConvert=stringToConvert.substring(2,laenge);					
				long teilstring=Long.parseLong(stringToConvert);						
				System.out.println("Client: Client verlangt Verzögerung um "+teilstring+" ms.");
				handler.waitTime(teilstring);
				toClient.write("Clock wurde um "+teilstring+" ms verzögert.");
				toClient.flush();
			}	
			
				toClient.close();
				fromClient.close();
				talkSocket.close();	
	
	}
	catch (IOException e) {e.printStackTrace();}
	catch (IllegalCmdException e) {e.printStackTrace();}
	//catch (InterruptedException e) {e.printStackTrace();}
	
	}
	
	}
}
```


----------



## SlaterB (4. Apr 2007)

Fehlermeldung? Zeile?
und welchen Sinn hat dieser ausfürliche Code 's', 'g' usw.?
die run-Operation sollte aus 10 Zeilen bestehen (in denen der Fehler auftritt)
nicht 100, wozu den Rest posten?

funktioniert es denn wenn du das ganze nicht in einem Thread laufen läßt?
Beispiel?


----------



## ven000m (4. Apr 2007)

Hi,

ja läuft ohne Thread, schon klar.



> at java.net.Socket.getInputStream(Unknown Source)
> at vsy.clockdemo.server.ServerThread.run(ServerThread.java:32)
> java.net.SocketException: Socket is closed
> at java.net.Socket.getInputStream(Unknown Source)
> ...



Ist das denn konzeptionell richtig? Also wenn ich den Socket in den Thread übergebe, dann darf ich doch normalerweise keine Bindung Probleme bekommen oder?  Gilt das ebenso für sonstige Variablen, werden die dann auch gesondert adressiert, damit sie sich nicht in die Haare kommen?


s,g,.. :
Der Server realisiert eine Clock und bekommt ein Char als Steuerung.


----------



## SlaterB (4. Apr 2007)

das es einen Unterschied zwischen Thread und nicht Thread gibt halte ich für ausgeschlossen,

mit deinem wirren Code kann man natürlich wenig erkennen,
schreibe dir eine Operation 
doSomething(socket) {
öffnen, schließen, maximal 10 Zeilen
}

von mir aus statisch oder sonstwas
und die rufst du einmal von der run aus und einmal normal vom Skeleton,
was geht wann nicht?

-------

in deiner run hast du ja eine Endlosschleife und zwischendurch ein
talkSocket.close();  
im zweiten Durchlauf wäre des Socket zu, passt zur Fehlermeldung...

schreibe am Anfang der Schleife
System.out.println("neuer Schleifendurchlauf");
wie oft erscheint die Meldung vor dem Fehler?


----------



## ven000m (4. Apr 2007)

Ausgabe kommt 1x.

Fehler:


> neuer Schleifendurchlauf
> 
> java.net.BindException: Address already in use: JVM_Bind
> 
> ...



Das 

	/*toClient.close();
				fromClient.close();
				talkSocket.close();	*/

habe ich komplett rausgenommen.


----------



## SlaterB (4. Apr 2007)

aha, das ist doch mal ein ganz anderer Fehler als vorher,
deshalb immer Fehlermeldung posten!

diese Fehlermeldung sagt dir, dass du zwei Server auf einem Port starten möchtest,
die Zeile
 ServerSocket listenSocket = new ServerSocket(4711); 
muss aus der Schleife im Skelefon raus,
reicht einmal vor der Schleife,
und muss erst ganz am Ende des Programmes geschlossen werden, nicht bei jedem Empfang 


du Einzelverbindungen musst du aber schon irgendwann mal schließen..


----------



## ven000m (4. Apr 2007)

Hi,

so dann der nächste Fehler.



> java.net.SocketException: Socket is closed
> at java.net.Socket.getInputStream(Unknown Source)
> at vsy.clockdemo.server.ServerThread.run(ServerThread.java:35)
> neuer Schleifendurchlauf
> ...



Das bekomme ich immer, so bald ich den Client mit "s" starte. (= also was in der Konsole eingebe..)

Weisst du wieder Rat? Danke


----------



## SlaterB (4. Apr 2007)

poste doch bitte mal einen aktuellen Stand, wenns geht mit 10 Zeilen in der Verarbeitung, 
Schleife usw. muss doch gar nicht sein oder?

und möglichst einen ebenso kleinen Client dazu, so dass man das ausprobieren kann


----------



## ven000m (4. Apr 2007)

Die Uhr kann ich mit "s" in der Konsole noch starten:

accepted commands:
  s[tart]     h[old]   c[ontinue]   r[eset])
  g[et time]  e[xit]   w[ait] 4711

command [s|c|h|r|e|g|w]: s
*Clock Timer gestartet.*
command [s|c|h|r|e|g|w]: 


Dann auf Serverseite:

at java.net.Socket.getInputStream(Unknown Source)
	at vsy.clockdemo.server.ServerThread.run(ServerThread.java:31)
java.net.SocketException: Socket is closed
	at java.net.Socket.getInputStream(Unknown Source)

Zeile31:

```
fromClient = new BufferedReader(new InputStreamReader(talkSocket.getInputStream(),"Cp1252"));
```


ServerThread.java:


```
package vsy.clockdemo.server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;


public class ServerThread extends Thread { 
	private Socket talkSocket; 
	
	public ServerThread(Socket talkSocket) 
	{ 
		this.talkSocket = talkSocket; 		
	}
	
	public void run()
	{
		//Socket talkSocket;
		BufferedReader fromClient;
		OutputStreamWriter toClient;
		String stringToConvert;
		
		String zeit="";		
		Clock handler = new Clock();
		
		while(true)
		{			
		try{			
			
			fromClient = new BufferedReader(new InputStreamReader(talkSocket.getInputStream(),"Cp1252"));
			toClient   = new OutputStreamWriter(talkSocket.getOutputStream(),"Cp1252");			
			stringToConvert= fromClient.readLine();	
			
			
			if(stringToConvert.charAt(0)=='s')
			{
				handler.start();
				toClient.write("Clock Timer gestartet.");
				System.out.println("Client drückt 'S'.");					
		    }
			
			if(stringToConvert.charAt(0)=='g')
			{
				toClient.write("Clock steht bei: "+handler.getTime()+"ms");					
				System.out.println("Client drückt 'G'.");		
				
		    }
			
			if(stringToConvert.charAt(0)=='r')
			{
				handler.reset();
				toClient.write("Clock wurde resettet.");
				System.out.println("Client drückt 'R'.");
		    }
			
			if(stringToConvert.charAt(0)=='h')
			{
				zeit=""+handler.halt();
				toClient.write("Clock wurde gestoppt bei: " +zeit+"ms");
				zeit="";
				System.out.println("Client drückt 'h'.");					
		    }
			
			if(stringToConvert.charAt(0)=='c')
			{
				handler.conTinue();
				toClient.write("Clock wird fortgesetzt bei "+handler.getTime()+" ms.");
				toClient.flush();
				System.out.println("Client drückt 'c'.");
									
		    }
			
			if(stringToConvert.charAt(0)=='e')
			{
				
				toClient.write("Clock wurde beendet.");
				toClient.flush();
				System.out.println("Client hat Uhr beendet.");
				handler.exit();
									
		    }
			
			if(stringToConvert.charAt(0)=='w')
			{
				int laenge=stringToConvert.length();					
				stringToConvert=stringToConvert.substring(2,laenge);					
				long teilstring=Long.parseLong(stringToConvert);						
				System.out.println("Client: Client verlangt Verzögerung um "+teilstring+" ms.");
				handler.waitTime(teilstring);
				toClient.write("Clock wurde um "+teilstring+" ms verzögert.");
				toClient.flush();
			}	
			
				toClient.close();
				fromClient.close();
				talkSocket.close();	
	
	}
	catch (IOException e) {e.printStackTrace();}
	catch (IllegalCmdException e) {e.printStackTrace();}
	//catch (InterruptedException e) {e.printStackTrace();}
	
	}
	
	}
}
```


----------



## SlaterB (4. Apr 2007)

ja spinn ich? die drei close sind ja wieder drin,
es fehlt Skeleton und Client..


----------



## ven000m (4. Apr 2007)

Hi,

wie gesagt die drei Close müssen rein!

Sonst tut nix und so war es bereits richtig ohne Threads. Die anderen Sachen reiche ich nächsten Mittwoch nach.


----------



## SlaterB (4. Apr 2007)

na mehr als helfen kann ich nicht,
zaubern musst du alleine


----------

