# Datein versenden funktioniert nicht !



## Guest (5. Feb 2008)

Hallo !

Ich habe eine Server/Client Anwendung geschrieben, mit der man einfach miteinander komunizieren kann. Jetzt sitze ich schon seit 3 Tagen bei meinem Problem und finde keine Lösung.

Mein Problem ist, wenn ich Datein versenden will, z.B. eine *.bmp Datei, dann list der InputStream von Java nur die ersten 4 Zeichen ein, weil ab den 5. Zeichen ein paar 0-Bytes gesendet werden, und sobald ein 0-Byte gesendet wird, hört der InputStream auf zu empfangen, weil er wahrscheinlich denkt das der Stream beendet sei (zum Empfangen)

Der Server ist in C und der Client in Java geschrieben, die Übertragung funktioniert enwandfrei, bis auf dieses Probelm mit dem  0-Byte...

Ich weiß wirklich nicht wie ich das Problem lösen kann, ich hoffe ihr könnt mir helfen  bin wirklich am Verzweifeln.


----------



## Guest (5. Feb 2008)

Achja es handelt sich um eine TCP/IP Verbindung


----------



## tuxedo (5. Feb 2008)

Ein Wenig Code wäre hilfreich. 

Offensichtlich hast du ja schon ein Problem was sich noch VOR dem versenden der Datei äußert. "Einlesen" über InputStream hört sich nämlich nach einem Filereader o.ä. an.

- Alex


----------



## Guest (5. Feb 2008)

Naja ein Problem das sich VOR dem versenden äußert ist nicht richitg, ich kann ja Daten versenden, aber sobald in der Datei ein 0Byte zum versenden ist, dann bricht java das einelsen über den InputSTream ab.

hier der Code vom Java Client, der die Datei empfängt und einlest, über einen Stream vom Socket. 


```
/*Array mit 0 fuellen*/
						for(int i = 0; i < buffer.length; i++) {
							buffer[i] = 0;
						}
						iResult = br.read(buffer,0,buffer.length);
						System.out.println("eingelesene zeichen: "+iResult);
						
						for (char c: buffer) {
							System.out.print(c);
							
						}
```

Ich schicke den Server eine Anfrage bezüglich einer Datei die ich downloaden will, dann sendet mir der Server die Datei (im binary modus natürlich).

Wenn ich auf der Server-Seite statt einem 0-Byte z.b eine 1 versende, dann funktioniert alles super.

Ich hoffe ich habe mich verständlich genug ausgedrückt.


----------



## Guest (5. Feb 2008)

@edit

Dass das Probelm Serverseitig ist denke ich nicht. Denn dort lese ich einfach die Datei die verlangt wird (falls vorhanden) mit einem filestream ein, und verpacke dann die bytes in 512Byte Pakete und versende diese.

Das char-Array "buffer" in Java ist auch 512 Zeichen groß.


----------



## tuxedo (5. Feb 2008)

*moment*

Zeig mal n bisschen mehr "drum rum". Wie initialisiertst du dein "br" ?

Dein "seltsames" Array-Initialisieren kannst du dir sparen.

- Alex


----------



## Gast (5. Feb 2008)

Nein, alle anderen Funktionen gehen wundebar, nur des downloaden einer Datei bekomm ich nicht hin.

Wenn die Datei keine 0 Bytes enthält, funktioniert der download auch wie gewünscht, aber sobald ein 0 Byte vorkommt, bricht es ab.

Ich meinte damit VOR dem einlesen ist nicht richtig, weil ich ja einlese und Daten ausgebe, aber wenn z.b Byte nr. 1025 ein 0 Byte ist, dann bricht der Download erst dort ab, und es werden die ersten 2 512Byte blöcke geschickt.

Das Array hab ich zu testzwecken mit 0 gefüllt, weil ich vorhin versucht habe, anstatt eines 0 Bytes eine 1 vom Server zu versenden, so hats auch geklappt, aber dann wär der Sourcecode der Datei eben falsch.

Vielleicht hab ich mich blöd ausgedrückt, mit einelsen meinte ich nicht die Datei direkt einelsen, sondern den bytstream der vom Server gesendet wird.

Die Datei wird auf den Server richtig und vollständig einglesen.


----------



## tuxedo (5. Feb 2008)

Würde das eigentlich so machen:


```
FileOutputStream fos = new FileOutputStream(new File("c:/x.xxx"));
		
		InputStream in = null; // hier halt deinen InputStream vom Socket. Würde keinen "BufferedReader" benutzen!
	
		byte[] buffer = new byte[128]; // Die puffergröße ist nahezu "schnuppe"
		int bytesRead = 0;
		
		while(bytesRead>=0){ // erst abbrechen wenn -1 bytes gelesen wurden, sprich der Stream zuende ist
			bytesRead = in.read(buffer);
			fos.write(buffer,0,bytesRead);	
		}
		in.close();
		fos.close();
```

Wenn der bei dir, in deinem jetzigen Code vorher abbricht, dann muss es eine Abbruch-Bedingung geben... Zeig mal deine komplette Schleife ...


----------



## Guest (5. Feb 2008)

```
/*File einelsen und ausgeben bis EOF (-1) erreicht wurde*/
					while (true) {
						
						/*Array mit 0 fuellen*/
						java.utils.Arrays.fill(buffer,0);
						
						iResult = br.read(buffer,0,buffer.length);
						if (iResult <= 0) break;
						System.out.println("eingelesene zeichen: "+iResult);
						
						for (int = 0; i < iResult; i++) {
							
							
							System.out.print(bffer[i]);
							
						}
						
						
					}
```


Hier ist der Fehler, die Funktion br.read(buffer,0,buffer.length) bricht ab sobald ein 0Byte eingelesen wird, obwohl die Datei noch lange nciht fertig gesendet wurde. Die Funktion liest die Daten ein die vom Server gesendet werden, und diese Daten sind die Filedaten.


----------



## tuxedo (5. Feb 2008)

Du willst damit also sagen:

- Der C-Server sendet ein 0-Byte
- Der Java-Client liest -1 Zeichen (iResult == -1) und Zeile 8 deines Codebeispiels greift und bricht die Endlosschleife

?? Ist das so korrekt? 

Wenn ja, dann ist der "Fehler" IMHO auf C-Seite zu suchen. Denn die read() Methode liefert erst dann -1 zurück wenn der Stream "beendet", spriuch EOF ist, und nciht wenn ein 0-byte kommt (hab ich ein Dutzend eigener Anwendungen die mit 0bytes umgehen können und nicht anders aussehen als mein Codebeispiel).

- Alex


----------



## Gast (5. Feb 2008)

@alex0801

Ich mach es doch eig. genau wie du, nur hab ich InputStreamReader verwendet (anfangs hatte ich BufferedReader, aber hab dann eh gleich gemerkt das der falsch dafür ist)

Nur habe ich noch nicht die bytes in eine Datei geschrieben, ich lass sie nur auf dem Bildschirm wiedergeben damit ich gleich sehe ob auch überhaupt alles übertragen wird. 

Ich versuch jetzt mal deine Methode aber ich bezweifle das diese nicht auch bei null bytes abbricht, hab schon fast alle streams druchprobiert


----------



## tuxedo (5. Feb 2008)

Wie schön dass du nicht auf meine Frage eingegangen bist und meinen letzten Satz augenscheinlich ignoriert hast.

BTW: Der InputStreamReader ist für Binärdaten nicht so geeignet.



			
				Java API Doc hat gesagt.:
			
		

> An InputStreamReader is a bridge from byte streams to character streams: It reads bytes and decodes them into characters using a specified java.nio.charset.Charset charset. The charset that it uses may be specified by name or may be given explicitly, or the platform's default charset may be accepted.



- Alex


----------



## Gast (5. Feb 2008)

@alex0801

Ok, kam mir auch etwas komisch vor warum 0Bytes bei Java nicht empfangen werden sollen.

Der C-Server sendet ein 0Byte das stimmt

Nur gibt die Funktion  br.read 1 zurück, als eingelesene Zeichen, aber bricht dann ab

Das hier ist die Ausgabe:

eingelesene zeichen: 4
66771029
eingelesene zeichen: 1
255

Dann kommt nichts mehr, auch die Kommunkation funktioniert nicht mehr mit dem Server weil er noch senden will, aber der Client empfängt keine Daten mehr.

Aber ich werde mal den Fehler beim Server suchen


----------



## Gast (5. Feb 2008)

@alex

Sry ich hab deinen Post erst gelesen also ich schon abgeschickt habe. Der post ober mir ist die Antwort darauf, und ich hab ja gesagt ich such jetzt mal bei der Serverseite nach einem Fehler


----------



## tuxedo (5. Feb 2008)

Wenn er nach 5 Zeichen (4+1) abbricht (bytesRead == -1), dann wurde offensichtlich der Stream beendet. Ein Debug-Output am Server sollte da klarheit verschaffen. Lasse dort einfach mitzählen wieviele Zeichen schon in den Siocket geschickt wurden. 

- Alex


----------



## HoaX (5. Feb 2008)

Anonymous hat gesagt.:
			
		

> ```
> /*File einelsen und ausgeben bis EOF (-1) erreicht wurde*/
> ...
> if (iResult <= 0) break;
> ...



wie ihr ja selbst sagt gibt read -1 zurück wenn der stream beendet ist. diese abfrage bricht aber auch bei 0 ab, was durchaus vorkommen kann wenn die daten schneller empfangen als gesendet werden. mach ein 
	
	
	
	





```
iResult != -1
```
 draus, wie es sich gehört. 

ebenso an alex, 
	
	
	
	





```
>=0
```
 ist falsch, weil was ist bei -2? in diesem context ist das noch "egal", aber ich kenne es z.B. von String#hashCode. dort wird 0 zurückgegeben wenn der string länge 0 hat. der kollege hatte die abfrage >0 gemacht. wir haben fast ewig gesucht bis wir darauf gekommen sind dass der wert bei manches strings negativ ist.

*langer rede kurzer sinn: wenn in der doc steht dass das ende des stream -1 ist, dann auch darauf prüfen, und nur darauf!*


----------



## tuxedo (5. Feb 2008)

Naja, >=0 sollte ebenso funktionieren. Ist zwar nicht hübsch, aber hat funktioniert. Und wenn man in den Source schaut, dann weiß man auch warum ;-)

Sollte ja auch keine Musterlösung sein, lediglich ein "so haut's zumindest mal hin".

Das <= 0 hab ich doch tatsächlich im Eifer des Gefechts übersehen. Klar, so kanns nicht klappen.

- Alex


----------



## HoaX (5. Feb 2008)

darum sagte ich ja dass es in diesem context egal ist, sondern so als anregung allgemein


----------



## tuxedo (5. Feb 2008)

Oh man, Zeit für den Feierabend... Schon wieder "überlesen"...

- Alex


----------



## Gast (5. Feb 2008)

Hallo !

Bin erst jetzt nach Hause gekommen desewgen konnte ich nicht mehr Antworten.

Ich hab das Problem jetzt endlich gefunden, dank einem Tipp von alex0801 

Und auch danke an dich Hoax, die falsche Bedingung hab ich übersehen.

Schönen Abend noch !!


----------

