# Dateitransfer - kein end of stream



## shizar (25. Jul 2011)

Ich will vom Client eine Datei zum Server übertragen, das funktioniert auch! aber leider wartet der Server im read() nach dem ende der übertragung! (also er erhält kein end of stream) weis einer von euch warum?

Senden der Daten:


```
int len = 0;
	while ((len = is.read(buffer)) > 0) // Auslesen der Datei und...
	{
		out.write(buffer, 0, len); //...Senden (Out ist ein OutputStream)
	}
```

Empfangen der Daten:


```
while ((byteCounter = in.read(buffer)) > 0) //in. ist ein InputStream
{
	os.write(buffer, 0, byteCounter); //os. Ist ein FileOutputStream
}
```

Also beim Empfangen wartet er im "in.read(buffer)" bis ein Timeout auftritt (durch setSoTimeout gesetzt), obwohl dmie Datei bereits vollständig übertragen ist!

Den Socket will ich aber noch nicht schließen, da ich dem Client noch eine Antwort schicken will (erfolgreich empfangen, oder eben eine Fehlermeldung...) 
Also nach dem Senden der Datei wartet der Client in einem read() auf eine antwort, läuft aber auch in ein Timeout da der Server keine antwort sendet (wartet ja noch im read()) 
was mache ich falsch?
danke


----------



## Ariol (25. Jul 2011)

Versuch mal nach dem Senden zu flushen.

Evtl. kannst du auch den OutputStream schließen und erhälst einen neuen gültigen bei getOutputStream(), dass ist aber nur eine Idee.


----------



## Kr0e (25. Jul 2011)

Du machst nichts falsch, sondern für dein Vorhaben einfach nur zu wenig 

Was du brauchst wären Metadaten. Also Daten über die Daten die du sendest. Wie wäre es mit einem 5-Byte - Header:


```
byte[] buffer = new byte[8192];

    buffer[0] = 0x01; //Das kannst du dir dann ja überlegen..

    int len = 0;
    while ((len = is.read(buffer, 5, buffer.length-5)) > 0) // Auslesen der Datei und...
    {
        //Schnell die Größe in den Header packen
        writeIntToByteArra(len); // Hab grad keine Lust dieses Byteverschieben auszuformulieren^^ 

        // Len + 5 weil dein Header byte groß ist: 1 byte Packetbeschreibung also in dem Fall 0x01 bedeutet, dass gleich ein Stück der Datei kommt..
        // Und ein int (4 byte) der die länge des datenblocks angibt...
        out.write(buffer, 0, len + 5); //...Senden (Out ist ein OutputStream)
    }
```

Wenn nun deine Datei fertig ist kannst du z.B. 0x02 als Byte-Flag schicken und dann auf der Gegenseite dieses sehr einfache Protokoll auswerten...

Also: STichwort: Protokoll!

Gruß,

Chris


----------



## shizar (25. Jul 2011)

Danke für Antwort!
hmm sowas wie ein Protokoll habe ich bereits, allerdings nicht mit Headern, sondern mit "out.write(int)" realisiert!, also der Server wartet auf eine verbindung und erhält eine integer Zahl, und anhand von der weiß er nun welche daten kommen, und empfängt diese dann, da er weis das zur zahl 12 die Daten X mit der länge 45Byte kommen (habe vordefinierte Nachrichtenlängen). Hmm was haltet ihr Prinzipiell von diesem System? Vielleicht doch besser nur mit Headern realisieren? ist das was ich mache in der Netzwerkkommunikation verpönt? kenne mich was diese richtung was die Konventionen betrifft nicht so super aus!
Bei Datein funktioniert dieses system eben nicht, da diese keine feste Länge besitzen. Bei Dateien wäre aber glaube ich ein 8Byte Header besser.. Integer.Max_VALUE könnte ein bisschen klein für große Dateien sein (auch wenn zu 99,9% nur kleine Datein (<5MB) verschickt werden sollen...


----------



## Kr0e (25. Jul 2011)

Ähm, ich war eben in Eile, besser wäre folgendes: Schreib am Anfang bevor du die Datei versendest eine long Zahl (8 byte) die die Gesamtgröße der Datei beschreibt. Der andere PC weiß dann, wann er aufhören muss zu lesen. Man kanns auch mit Headern machen, aber ist garnicht mal notwendig  So ist vorallem sichergestellt, dass der andere PC weiß wieviel kommt und kann dann ne PRogressbar anzeigen oder so 

GRuß,

CHris


----------



## Gelöschtes Mitglied 5909 (25. Jul 2011)

Übrigens ist die korrekte abbruchbedingung der while schleife != -1 und nicht > 0

// edit 2

übrigens hast du das problem auch nur dann, wenn die verbindung nach dem dateitransfer geöffnet bleibt. Ob das gewünscht ist musst du wissen. Protokolle wie ftp machen die kommunikation und den datentransfer über unterschiedliche kommunikationskanäle (sockets)


----------

