# Blockierender Server



## duddel123 (8. Jul 2005)

Hallo zusammen, folgendes Problem:

Ich haben eine Server und einen Client. Der Server empfängt zu allererst durch eine InputStream eine Zeile vom
Client. Steht in dieser Zeile zu Anfang "1234" so schickt er dem Client "File schicken" Dieser Client reagiert auf "File schicken" und schickt durch (siehe unten sendFile) das File zum Server. Der Server empfängt dieses File auch tadellos.
anschließend möchte ich aber wieder direkt auf einen Eingang von dem Client reagieren können und habe deshalb eine while(true) angesetzt. Sobald der Server wieder auf eventIn(), also den InputStream auswertet ,steht der Server auf 100% CPU. Für den File Transport verwende ich aber nicht den gleichen Stream sondern (siehe unten) einen BufferedStream. Ich vermute, das es was mit dem Stream schliessen von Seiten des Client zutun hat, aber wenn ich diesen Stream nicht schließe, dann merkt meine receive niemals, das das File zu Ende ist. Er erreicht somit 
	
	
	
	





```
while(read!=-1) {
```
 nie. Hat jemand vielleicht eine Idee, bzw. vielleicht auch einen anderen Ansatz um auf Server Client Events zu reagieren, ich möchte eigentlich nur, dass der Server ständig Event vom Client auswerten kann und dann je nach Bedarf Files empfängt oder weitere Anweisung etc.

g duddel123

PS: Try catch Blöcke habe ich rausgenommen!!

Server:
------------------


```
public void run(){
	while(true){
		Thread.sleep(10);
		requestFromClient = eventIn();				
			if(requestFromClient.startsWith("1234")){
				eventOut("File schicken"+"#");
			}
			else{
				eventOut("Das hast du Toll gemacht"+"#");
			}
	receiveFile(incomingData,outXML);
	}
}//run
```





```
private void receiveFile(BufferedInputStream incoming,FileOutputStream out) {
    // Lese 
    long read = (long)incoming.read();
    // Schreibe
        while(read!=-1) {
            out.write((int) read);
            read = (long)incoming.read();
    }//while

    // Schliesse die Datei
    out.close();
}//receiveFile
```

Client:
-----------------

```
private void sendFile(BufferedOutputStream outgoing, FileInputStream fis) {
long read = (long) fis.read();
        	while (read!=-1) {
                    outgoing.write((int) read);
                    read = (long) fis.read();
        	}//while
        	
        	outgoing.flush();
        	// Schliesse Stream- Verbindung zum Server 
        	outgoing.close();
}//sendFile
```


Server und Client:
--------------------------------

```
public static String eventIn(){
    String requestFromClient = null;
    String tempRequestFromClient = null;
    char byteFromStream;
    char char1=35; // #
	while ((byteFromStream = (char) eventIn.read()) != -1) { 
	    if(byteFromStream==char1){
	        requestFromClient=tempRequestFromClient.substring(4);
	        break;//while Abbruch
	    }//if
                tempRequestFromClient = tempRequestFromClient + byteFromStream;
	}//while
    return requestFromClient;
}//eventIn
```



```
public static void eventOut(String datensatz){
    toClientOut.println(datensatz);
    toClientOut.flush();
}//eventOut
```


----------



## hugo (8. Jul 2005)

duddel123 hat gesagt.:
			
		

> ```
> public void run(){
> while(true){
> Thread.sleep(10);
> ...


Dein erstes Problem fängt ja schon an der Stelle an, dass du auch auf ein File wartest, wenn die "1234" nicht gesendet wird.



			
				duddel123 hat gesagt.:
			
		

> ```
> public static String eventIn(){
> String requestFromClient = null;
> String tempRequestFromClient = null;
> ...



Warum brichst du die Schleife nicht schon ab, beim auftreten von char(35)? Den Substring kann man im Anschluss so oder so noch bilden. Und ein StringBuffer würde sich für das Einlesen von vielen Charactern auch besser eigenen. Da man aus den Codestücken eben nicht sehen kann, ob ein Stream offen ist, könnte es sein, dass er die ganze Zeit irgendwelche (Null)Bytes einliest. Das könnte die CPU-Last vielleicht erklären.

Es wäre vielleicht auch ganz hilfreich ein wenig mehr von der Klasse zu zeigen, da man hier auch nicht erkennen kann, wann einzelne Streams geöffnet bzw. geschlossen werden.

Ich würde an deiner Stelle auch die Sockets (in alle richtungen) schließen und für eine neue Verbindung neu aufmachen. Somit kommst du nicht in die Verlegenheit, die ganze Zeit am Horchen zu sein.


----------



## duddel123 (8. Jul 2005)

hugo hat gesagt.:
			
		

> Dein erstes Problem fängt ja schon an der Stelle an, dass du auch auf ein File wartest, wenn die "1234" nicht gesendet wird.



Ja ich weiß, ist aber nicht das Problem, da der Client zur Zeit noch immer "1234" sendet, in der nächsten Stufe kommt das natürlich raus! danke, trotzdem



			
				hugo hat gesagt.:
			
		

> Und ein StringBuffer würde sich für das Einlesen von vielen Charactern auch besser eigenen.



Es sind eigentlich Nur "12345;12345;12345#" lange Zeichenketten, müßte doch eigentlich ausreichen oder??



			
				hugo hat gesagt.:
			
		

> Es wäre vielleicht auch ganz hilfreich ein wenig mehr von der Klasse zu zeigen, da man hier auch nicht erkennen kann, wann einzelne Streams geöffnet bzw. geschlossen werden.



mmmh Also für den Server sind alle Klassen vorhandenen, das einzige was bis jetzt abläuft ist, ist in der run() zu sehen!
1.requestFromClient = eventIn();
2....startsWith("1234")
3. eventOut("File schicken"+"#");
4. receiveFile(incomingData,outXML);
und dann wieder von vorne!!

Es wird wohl an "Null)Bytes einliest" liegen aber ich finde da leider nicht das Problem



			
				hugo hat gesagt.:
			
		

> Ich würde an deiner Stelle auch die Sockets (in alle richtungen) schließen und für eine neue Verbindung neu aufmachen. Somit kommst du nicht in die Verlegenheit, die ganze Zeit am Horchen zu sein.



mmh also für jeden event ein neuen Socket aufmachen und wieder alles abbauen... O.k. würde natürlich das Problem lösen, allerdings möchte ich in einem zweiten Schritt, das der Server auch einen Request an den Client abgibt, was dann nicht gehen würde!!!

Noch Idee????, Ich hoffe!!


----------



## duddel123 (8. Jul 2005)

Also ich habe noch mal geguckt....und er hängt direkt in der 
	
	
	
	





```
while ((byteFromStream = (char) eventIn.read()) != -1) {
```
 von eventIn().... könnte man das reset'en ???


----------



## hugo (8. Jul 2005)

Lass dir doch einfach mal die Charakter ausgeben, die du einliest, und zwar jedes mal, bevor du sie an den String hängst. So sieht man jedenfalls, was er macht. Und dann einfach mal schauen, was der Charakter für ein Wert hat, falls er komisch aussieht.
Resetten ist bestimmt kein Problem, du musst dir in der Schleife nur einfallen lassen, unter welchen Bedingungen er etwas zurücksetzt oder rausspringt.
Was den StringBuffer betrifft ist der einfach mal von der Performance besser beim hinzufügen von weiteren Buchstaben. Strings sind eigentlich nicht dafür gedacht erweitert zu werden.
Was für einen Stream verwendest du eigentlich um dein eventIn auszulesen? Kann es darin liegen, dass er immer diese Dummy-Bytes einliest?


----------



## duddel123 (8. Jul 2005)

Also es kommt ständig eine Fragezeichen an "?" und das dauernd. Auf dem eventIn Stream liegt ein einfacher InputStreamReader noch kein BufferedReader. Das habe ich gemacht, weil ich mal ständig Timing Probleme unter Java 1.4 mit BufferedStreams hatte, kann natürlich sein, dass das unterm Tiger behoben ist, weiß ich nicht!!


```
char char2=63; // ist ein ?
if(byteFromStream==char2){
    break;
}
```

Innerhalb der while Schleife abgefragt, erreicht nie das break; auch sehr merkwürdig, weil beide vom Typ char sind und eigentlich beide die 63 bzw. das ? enthalten !!! Das kann doch eigentlich nur ne Kleinigkeit sein oder?? Nerv.. :?


----------



## hugo (11. Jul 2005)

Dieses Fragezeichen muss nicht unbedingt wirklich das Fragezeichen sein. Es könnte genauso gut ein nicht darstellbares Zeichen sein, bloß die Konsole macht daraus ein Fragezeichen. Versuch mal anstatt in char ind int zu casten und dann die Zahl die dabei herauskommt zu analysieren.
Was die Streams betrifft, muss ich ja sagen, dass ich den BufferedReader bevorzugen würde. Leider kann ich dir auch keien Alternative zum BufferedReader nennen. Aber ich glaube, dass der InputStreamReader für dieses "?" verantwortlich ist. Also wenn möglich vielleicht doch auf den BufferedReader umsteigen.


----------

