# Nach Dateiversand werden keine Nachrichten mehr übertragen



## Javax123 (12. Aug 2011)

Hallo,

ich übertrage eine Datei mittels einer Socket Verbindung von 2 Java Anwendungen folgendermaßen:

Server (Senden):


```
byte[] buffer = new byte[16384];
InputStream inputStream = new FileInputStream(f);
OutputStream outputStream = client.getOutputStream();
int len = 0;
while ((len = inputStream.read(buffer)) > 0) {
  outputStream.write(buffer, 0, len);
}
```

Client (Empfangen):


```
byte[] buffer = new byte[16384];
int len = 0;
while ((len = is.read(buffer)) != -1) {
fs.write(buffer, 0, len);
}
```

Wobei hier "fs" der FileOutputStream und is der InputStream des Sockets darstellt.

Das ganze funktioniert auch wunderbar. Das Problem ist jedoch wenn ich nun danach vom Server nochmal eine Nachricht absende, etwa per "outputStream.write(987654321);" und versuche die danach auf der Client Seite wieder mit "int test = is.read();" zu lesen, kommt diese nicht mehr an.

Hat jemand eine Idee was ich dabei falsch mache?

Vielen Dank!


----------



## SlaterB (12. Aug 2011)

du verwendest eine Standardschleife, die bis -1, also Stream-Ende liest,
das passiert wirklich zum Ende der Verbindung, nicht bis du beim Server mit der Schleife oder einer bestimmten Methode fertig bist, wie soll der Client das erkennen?
verwende Protokolle, sende z.B. vor der Datei die Anzahl der folgenden bytes an Daten, dann die Schleife nicht bis -1, sondern nur bis genug Daten gelesen sind oder ähnliches


----------



## Javax123 (15. Aug 2011)

Hey Slater,

danke für deine Antwort, das ganze klingt auch recht Einleuchtend, nur dachte ich bisher das der Sendevorgang dadurch beendet ist wenn die Array Länge des Bytes Array durchlaufen wurde.

Kannst du mir ganz grob Beispielhaft zeigen wie ich die Schleife so ummodellieren kann das er die Länge richtig wählt? Ich kann mir das grade leider nicht wirklich vorstellen, wäre dir wirklich sehr dankbar!

Gruß


----------



## SlaterB (15. Aug 2011)

du hast alle Zeit der Welt zum Nachdenken und Ausprobieren,
das fängst schon mit einer einfachen Datei von 5 Bytes ab, ganz ohne Schleife,
wenn du nichts an Code selber schreibst oder konkrete Fragen stellst, dann sehe ich keinen Sinn darin irgendwas vorzugeben,

dass die len-Variable Information über die Anzahl gelesener Zeichen enthält ist dir schon bekannt,
oder ist der jetztige Code auch bereits nur irgendwo kopiert?
ich habe leider kein Interesse, für dich zu programmieren


----------



## Javax123 (16. Aug 2011)

Hi,

also mit folgenden Code sende ich ja die Datei:


```
while ((len = inputStream.read(buffer)) > 0) {
				outputStream.write(buffer, 0, len);
				System.out.println(len); // Habe ich eingebaut um die Anzahl der Zeichen zu prüfen
			}
```

Durch die Ausgabe sehe ich das bei meiner kleinen Datei nur ein Schleifendurchgang benötigt wird da es sich laut Ausgabe um 12935 Zeichen also Byte handelt.

Nun will ich also davor die Zeichenlänge mitschicken um auf Client Seite dann so lange empfangen zu können bis alle Zeichen durchlaufen sind.

Deswegen habe ich durch


```
int fileSize = (int)f.length();
			outputStream.write(fileSize);
```

versucht die Dateigröße in Bytes zu ermitteln... komischerweise bekomme ich hier allerdings einen Bytewert von 135 zurück, das müssten doch aber theorertisch gleich viel Bytes sein oder? Also die Dateigröße und die Zeichen einer Datei die eiingelesen werden..?

Danke


----------



## SlaterB (16. Aug 2011)

prüfe doch erstmal beim Sender, was das eingelesene fileSize ist, 
wenn du noch nicht weißt, ob dieser Wert 125 oder der korrekte ist, dann wäre das für dich und alle eine wichtige Info,
wenn du es schon weißt, dann teile es allen anderen mit

vermutlich ist der Fehler: du schreibst die File-Size als int, das sind 4 Bytes, liest aber auf Empänger-Seite nur ein Byte davon,
verwende evtl. DataInputStream readInt()

edit:
wobei das Senden mit
outputStream.write(fileSize);
auch schon falsch sein könnte, da wird vielleicht nur ein Teil des ints verschickt, nur ein Byte,
verwende da auch DataOutputStream


----------



## Javax123 (16. Aug 2011)

Hey! Großes Dankeschön an dich! Mit dem DataOutputWriter hat das ganze funktioniert! Ich handle das auf Client Seite nun folgendermaßen:


```
DataInputStream dis = new DataInputStream(is);
			int fileSize = dis.readInt();
			
			// Datei-Inhalte schreiben:
			byte[] buffer = new byte[16384];
			int len = 0;
			while ((len = is.read(buffer)) != -1) {
				fs.write(buffer, 0, len);
				if (len == fileSize)
				{
					break;
				}
			}	

			fs.flush();
			fs.close();

			System.out.println(br.readLine());
```

Und nun kommen auch bei der letzten Ausgabe in der letzten Zeile die Daten an die ich nach dem File gesendet habe =)

Danke!!


----------



## SlaterB (16. Aug 2011)

is.read(buffer)
hier musst du das Lesen maximal auf die noch offenen bytes beschränken, also zusätzlichen Parameter übergeben und zwischendurch ständig rechnen,
sonst liest du vielleicht zu viel ins Array, falls direkt danach weitere Daten folgen

überhaupt musst du in der Schleife die len-Werte addieren


----------



## Javax123 (16. Aug 2011)

Ich hatte es zuerst probiert in dem ich hier anstatt

```
len = is.read(buffer)) != -1
```

auf
	
	
	
	





```
len = is.read(buffer)) != fileSize
```

abgefragt hatte, dann ist mir das allerdings immer abgestürzt ...


----------



## SlaterB (16. Aug 2011)

in deinem Beispiel für mich nicht ganz verständlich falls danach der Vergleich 'len == fileSize' funktioniert,
letzlich aber eh keine gute Lösung, denn wegen der Schleife kommt ja grundsätzlich angenommen nicht alles auf einmal an usw.


----------



## Javax123 (16. Aug 2011)

Also du meinst dann quasi auf der Serverseite schon die Anzahl der benötigten Schleifendurchgänge berechnen und diese als Parameter mitschicken?


----------



## SlaterB (16. Aug 2011)

nein, das ist unnötig, zumal auch noch abhängig von der Buffer-Größe, die nicht übereinstimmen muss,

der Server sagt nur dass 100.000 Daten kommen,
der Client kann nun 100.000x ein Byte lesen, versuchen ein genau passendes 100.000er-Array zu lesen 
oder in einer Schleife ein beliebiges Array,
wenn beim ersten Schleifendurchlauf 8000 Bytes reinkommen dann kann man doch leicht ausrechnen dass noch 92.000 über sind, die Schleife noch nicht zu beenden ist,
das kriegt der Client, also du beim Client-Programmieren, alles hin, nur anstrengen

wenn die Gesamtmenge nicht bekannt ist kann der Client nicht zaubern, andere Dinge sind aber gut berechenbar


----------

