# Datei per Netzwerk senden



## Akrillo (22. Okt 2009)

Hallo Leute,

ich habe ein kleines Problem mit dem versenden von *.wav Dateien.
Wenn ich kleine Dateien(ca 19 kb) sende kommen Sie in richtiger größe an und ich kann die kopierte Version auch abspielen.
Falls ich eine große Datei(meine testdateien waren ca. 43 MB und 2 MB groß) kommt sie viel größer an ( Bei mir war die Kopie ca 83 MB und 3,3 MB groß)

Die Daten werden ganz normal über Socket und TCP übertragen.

Hier mal mein Code Schnipsel:
Sender:

```
FileInputStream inputStream = new FileInputStream(musikDatei);
             int len = 0;
             byte[] buffer = new byte[16384];
             
			
			//Sende Signal damit client weiß dass eine Datei übertragen wird
			out.println(musikDateiSignal);
			
			while ((len = inputStream.read(buffer)) > 0) {
                out.write(buffer, 0, len);
                System.out.println(buffer);
            }
			out.println('\0');
			out.println(musikDateiSignal);
		    System.out.println(clientIP + ": Musik - " + "sended");
		    out.println("Lied ist nun zuende...");
		    out.flush();
```

Empfänger:


```
System.out.println("Empfange Datei..."); //TODO rausnehmen  
//			            OutputStream datei = new FileOutputStream(file);
			            BufferedWriter datei = new BufferedWriter(new OutputStreamWriter(new FileOutputStream( "/home/akrillo/Downloads/webradio.wav" ) ) );

						while( (((msg = in.readLine()) != null)) && !msg.equals(musikDateiSignal))
						{
							datei.write(msg);
						}
				        System.out.println("Fetching complete.");
```

Meine Socket Erzeugung:


```
try{
			int port = Integer.parseInt(args[0]);
			int calls = 0;
			System.out.println("Listening Port to: " + port);
			ServerSocket server_socket = new ServerSocket(port);
			while(true){
				Socket socket = server_socket.accept();
				new Thread(new WebradioClientThread(++calls, socket)).run();
			}
		}catch(IOException e)
		{
			System.err.println("Connection error: " + e.toString());
			System.exit(1);
		}
```

danke für die Hilfe

ciao


----------



## musiKk (22. Okt 2009)

Binäre Daten nicht mit Reader und Writer lesen und schreiben, sondern mit Streams. Warum schreibst Du ein \0, wenn die Datei durch ist?


----------



## Gast2 (22. Okt 2009)

musiKk hat gesagt.:


> Binäre Daten nicht mit Reader und Writer lesen und schreiben, sondern mit Streams. Warum schreibst Du ein \0, wenn die Datei durch ist?



aus dem gleichen Grund wieso er StreamReader für binäre Dateien verwendet ... ihm ist der Unterschied zwischen Strings (menschlich Lesbar) und Binärdaten (CPU) nicht bekannt

hand, mogel


----------



## Akrillo (22. Okt 2009)

Hey leute, danke für die Antworten.

Ich habe jetzt folgendes umgestellt:

Server:

```
out = socket.getOutputStream();
in = socket.getInputStream();
...
 byte[] buffer = new byte[16384];
 java.io.InputStream inputStream = new FileInputStream(musikDatei);
 int len = 0;
  while ((len = inputStream.read(buffer)) > 0) {
      out.write(buffer, 0, len);
 }
  System.out.println(clientIP + ": Musik - " + "sended");
```

Client:

```
System.out.println("Empfange Datei..."); //TODO rausnehmen
						    File file = new File("/home/akrillo/Downloads/webradio.wav");
								
					            OutputStream outputStream = new FileOutputStream(file);
					            
					 
					            byte[] bufferFile = new byte[16384];
					            
					            while ((len = in.read(buffer)) > 0) {
					            	outputStream.write(bufferFile, 0, len);
					            }
					            System.out.println("FERTIG");
```

Nun erkennt der Client nun nicht das Ende der Datei und hängt ewig in der while schleife:


```
while ((len = in.read(buffer)) > 0) {
	outputStream.write(bufferFile, 0, len);
}
```

Hat jemand eine Idee wie ich dieses Problem umgehen kann ?

lg


----------



## Michael... (22. Okt 2009)

Akrillo hat gesagt.:


> Hat jemand eine Idee wie ich dieses Problem umgehen kann ?


 Verwende ein Protokoll, in dem Du die relevanten Daten überträgst. z.B.:
byte[0...3]Dateilänge x in Byte
byte[4...(3+x)]Datei

So kann man auch noch Informationen wie Dateiname und weitere Metainformationen mit übertragen.


----------



## musiKk (22. Okt 2009)

Musst Du mehrere Dinge über den Stream übertragen oder brauchst Du diesen speziellen nicht mehr, wenn die Datei fertig ist? Im ersten Fall gehts wie Michael... sagt, sonst kannst Du den Stream einfach schließen, dann liefert [c]read()[/c] -1 und die while-Schleife wird beendet.


----------



## Akrillo (22. Okt 2009)

Also kurz zu der kleinen Java APP

Es soll ein WebRadio werden, also Client und Server.
Das heißt der Kanal bleibt so lange offen bis der Benutzer die Verbindung per Konsoleneingabe beendet. Das heißt der Datenstrom bleibt die ganze zeit bestehen.

Ich werd das mal von Michael versuchen und meld mich falls nochmal Probleme auftreten.

bis dahin, danke !


----------



## HoaX (22. Okt 2009)

Btw. solltest du beim InputStream.read auf != -1 prüfen und nicht auf >0. a) weil in der Doku steht das Ende ist bei -1 erreicht und b) weil vorallem beim Netzwerk eine 0 durchaus auftreten kann.


----------



## Akrillo (22. Okt 2009)

Ok danke für den Hinweis

Also leute soweit funktioniert das ganze schon!
Nun überträgt es aber die Daten recht langsam, dies liegt an folgender StreamRead Technik:


```
OutputStream outputStream = new FileOutputStream(file);

					            
					            
					            for(int i = 0 ; i < fileSize; i++) {
					            	len = in.read();
					            	outputStream.write(len);
					            	System.out.println(((double)i/(double)fileSize)*100 + "%");
					            }
```

Nun habe ich versucht mehre Bytes mit einmal zu verschicken womit das Übertragen auch viel schneller geht


```
byte[] bufferFile = new byte[16384];
					            int rounds = (int)Math.floor(fileSize / bufferFile.length);
					            if (rounds == 0)
					            	rounds = 1;
					            for(int i = 0; i<=rounds; i++)
					            {
					            	in.read(bufferFile);
					            	outputStream.write(bufferFile);
					            }
					            outputStream.flush();
```

Jedoch wenn ich diesen Weg gehe spielt es meine Audio Datei auch erfolgreich ab, mit einer sehr viel kürzeren Übertragungsdauer, jedoch spinnt dann meine Konsole total rum und es werden komische Daten ausgegebn, so als würde der Server noch weitere Daten schicken ... 
Kennt jemand einen sauberen schnellen weg alle Bytes aufzufangen wie bei der oberen Methode jedoch mit mehr Übertragungsgeschwindigkeit?

danke für eure Hilfe

LG
Akrillo


----------



## musiKk (22. Okt 2009)

Du musst erfassen, wie viele Bytes überhaupt durch [c]read()[/c] gelesen wurden. Der Buffer muss nicht immer voll sein. Ich weiß aber nicht, ob das das Problem ist, weil ich nicht weiß, inwiefern die Konsole rumspinnt.


----------



## Akrillo (22. Okt 2009)

Also es werden einfach ganz viele undefinierbare Zeichen ausgegebn, im Reiterkopf der Shell stehen auch komische Zeichen ....

Ich übertrage ja vorher die Anzahl der Bytes die übertragen werden müssen... Und die Wav Datei wird dann auch ordnungsgemäß abgespielt jedoch zerstört es die Ausgabe und sieht einfach mal ... aus ;p

update:

ich habe festgestellt das sich einiges verändert wenn ich:

```
File file = new File("/home/akrillo/Downloads/webradio.wav");
								
					            OutputStream outputStream = new FileOutputStream(file);
					            byte[] bufferFile = new byte[3812];
					            int rounds = (int)Math.floor(fileSize / bufferFile.length);
					            if (rounds == 0)
					            	rounds = 1;
					            for(int i = 0; i<=(rounds); i++)
					            {
					            	in.read(bufferFile);
					            	outputStream.write(bufferFile);
					            }
					            outputStream.flush();
```

mit 

```
byte[] bufferFile = new byte[3812];
```

der Größe des Buffers herumspiele es manchmal geht, manchma große Fehler bei der Ausgabe gibt, und manchmal einfach hängt... woran könnte das liegen, oder hat jemand eine andere idee die Datei auf eine andere Art zu füllen.

update:

Hab am Server etwas umgestellt
vorher:

```
while ((len = inputStream.read(buffer)) > 0) {
      out.write(buffer, 0, len);
 }
```
nachher:

```
while ((len = inputStream.read(buffer)) > 0) {
	            out.write(buffer);
	        }
```

aufeinmal gehts... jemand eine idee warum das so ist ?

Möchte mich nochmals bei allen bedanken 

LG
Akrillo


----------

