# Dateien versenden



## Stiewen (26. Feb 2006)

Aloa he!

Ich habe ein Problem mit der Dateiversendung in einem lokalen Netzwerk!

Hier mein Source bisher:

Sender:

```
public void run (  ) {
    try {
      FileInputStream fisIn = new FileInputStream(strFile);
      OutputStream osOut = soClient.getOutputStream();
      File fi = new File(strFile);
      int intTemp;
      longFileSizeLeft = fi.length();
      longMaxBuffer = Long.parseLong(strFileLength);
      byte[] b = getBuffer();
      while ( fisIn.read(b) != 0 ) {
        osOut.write(b);
        osOut.flush();

        // BufferSize von der Restgroesse der Data abziehen
        longFileSizeLeft -= b.length;

        // neuen Buffer anlegen
        b = getBuffer();
        
        jpbTransfered.setValue(intProcess++);
        jlbInfo.setText("Transfered: " + (intProcess / 1024) + " kB/ " + (Integer.parseInt(strFileLength) / 1024) + " kB");
      }
      fisIn.close();
      jbuStatus.setText("Sender OK");
    } catch ( IOException ioe ) {

    }
  }

  public byte[] getBuffer (  ) {
    if ( longFileSizeLeft >= longMaxBuffer ) {
      return new byte[(int)longMaxBuffer];
    } else {
      return new byte[(int)longFileSizeLeft];
    }
  }
```
Server:

```
public void run (  ) {
    try {
      InputStream isIn = soClient.getInputStream();
      OutputStream osOut = new FileOutputStream(database.strHomeDir + strFile);
      longFileSizeLeft = Long.parseLong(strFileLength);
      longMaxBuffer = Long.parseLong(strFileLength);
      int intTemp;
      byte[] b = getBuffer();
      while ( isIn.read(b) != 0 ) {
        osOut.write( b );
        osOut.flush();

        // BufferSize von der Restgroesse der Data abziehen
        longFileSizeLeft -= b.length;

        // neuen Buffer anlegen
        b = getBuffer();
        
        jpbTransfered.setValue(b.length);
        jlbInfo.setText("Transfered: " + (b.length / 1024) + " kB/ " + (Integer.parseInt(strFileLength) / 1024) + " kB");
      }
      osOut.close();
      jbuStatus.setText("Server OK");
    } catch ( IOException ioe ) {

    }
  }

  public byte[] getBuffer (  ) {
    if ( longFileSizeLeft >= longMaxBuffer ) {
      return new byte[(int)longMaxBuffer];
    } else {
      return new byte[(int)longFileSizeLeft];
    }
  }
```

Prob: ich bekomm, wenn ich zB. ein Bild sende immer nur einen Teil von dem Bild perfekt an und den Rest mit anderen Farben oder gar nicht... 

Sollte ich bei dieser Übertragung bleiben oder auf DatagrammSockets über gehen, von denen ich noch keinen blassen Dunst habe und somit um ein kleines Beispiel bitten würde, wenn dies notwendig ist.

Danke, Stiewen


----------



## Beni (26. Feb 2006)

Ein InputStream füllt nicht immer den gesammten byte[] Buffer auf, den man ihm übergibt, er sagt aber wieviel bytes er tatsächlich geschrieben hat. Write hat ein ganz ähnliches verhalten, und schreibt nicht immer alles... das würde ich abfangen und beim schreiben auf die Festplatte berücksichtigen.


----------



## Bleiglanz (26. Feb 2006)

falsche Abbruchbedingung?

=> vergleich mit -1 bei read!!!!

du hörst auf, wenn das erste mal 0 kommt; und das kann durchaus mal passieren wenn gerade nichts da ist...


----------



## Stiewen (26. Feb 2006)

Gut gut...
Also:
@Bleiglanz: ich weiß, dass man es mit -1 macht, aber komischer Weise hängt er sich bei mir dann immer auf... heißt: er scheint unendlich daten zu schicken... *ANNOYED*

@Beni: Wie sollte ich was machen? *ANNOYED* ^^


----------



## Beni (26. Feb 2006)

Für den Server könnte das in die Richtung gehen:

```
byte[] buffer = new byte[1024];
while( ... ){
  int read = 0;
  // read
  while( read < buffer.length ){
    int delta = fileInput.read( buffer, read, buffer.length - read );
    if( delta == -1 )
      break;
    read += delta;
  }

  // write
  int write = 0;
  while( write < read ){
    int delta = socketOut.write( buffer, write, read - write );
    write += delta;
  }
}
```


----------



## Bleiglanz (26. Feb 2006)

Warum hat dein Sender kein osOut.close()?

und bitte keine leeren catch-Klauseln im Code


----------



## Stiewen (26. Feb 2006)

geht gut
@Bleiglanz: Kein osOut.cose(), weil ich hörte, und auch bemerkte, dass dadurch auch alle anderen Streams geschlossen werden. Und da ich einen Messanger schreibe, habe ich einen Stream für den Text und für die Dateien ... und wenn ich close mache nach der Übertragung, kann ich keinen text mehr senden :meld: :bae:

@Beni: Ich bekomme bei der write-schleife eine Meldung: in der zeile (b ist mein buffer)

```
delta = osOut.write(b, write, read - write);
```
Meldung: 
incompatible types
found: void
required: int

 :autsch:


----------



## Bleiglanz (26. Feb 2006)

> Kein osOut.cose(), weil ich hörte, und auch bemerkte, dass dadurch auch alle anderen Streams geschlossen werden


versteh ich nicht, warum verwendest du nicht 2 getrennte Sockets für Text und Dateien

mit einem kanns so nicht gehen, da müsstest du dir ja Start- und Stopzeichen selber überlegen (also eine Art Mini-Protokoll)

Wie soll denn bei deinem Schema überhaupt das Ende einer Datei erkannt werden


----------



## Beni (26. Feb 2006)

Stiewen hat gesagt.:
			
		

> @Beni: Ich bekomme bei der write-schleife eine Meldung: in der zeile (b ist mein buffer)
> 
> ```
> delta = osOut.write(b, write, read - write);
> ...


Oh, da hatte ich was falsch in Erinnerung. Ok, dann gibts eine Schleife weniger und nur ein einfaches "osOut.write", ohne das delta.

Aber beim "read" bleib ich dabei, das muss man gesondert behandeln (und diesmal habe ich in der API nochmal nachgeschaut).


----------



## stiewen (26. Feb 2006)

Also, ich komm net mehr klar!
wie soll ich denn bitte ordentlich bytes verschicken, wenn write nicht ordentlich funzt?
WER HAT DEN DRECK PROGRAMMIERT??????????
 :lol:  :lol:  :lol:  :lol:  :lol:  :lol:  :lol:  :lol:  :lol:  :lol:  :lol:  :lol:  :lol: 
kleiner scherz...  :noe: 
ICH BIN JAVA-FAN ^^


So, schluss mit lustig: Wie soll ich das denn nun machen, hab am oben genannten source rumgebastelt mit dem überprüfen, dass er ordentlich ordentlich ausliest, habs aber wieder weg genommen, weil der es auch nicht besser war.
ich weiß nicht, wie ich weiter machen soll oder geschweige denn anfangen soll das prob zu beheben ... ich bedanke mich für jede Hilfe, wenn sie nicht so aussieht, dass gesagt wird, dass ich 5 seiten API durchlesen soll oder sowas ...


----------



## Bleiglanz (26. Feb 2006)

also nochmal

wenn du kein close machst, kannst du mir dann bitte mal erklären, wie dein Empfänger das Ende des Sendevorgangs überhaupt jemals erkennen soll???


----------



## stiewen (26. Feb 2006)

Also, ich stürze mich jetzt einfach mal in die Klassen DatagrammSocket und DatagrammPacket rein
Wer dies verhindern möchte, sollte bitte grund und andere lösung bereit stellen ... 
@bleiglanz: ich dachte, dass wenn einfach mal kein byte mehr gesendet wird oder der rest des buffers leer ist, ein -1 oder 0 überreicht wird... aber ich versuche das jetzt mit den beiden klassen zu umgehen


----------



## Beni (26. Feb 2006)

DatagrammSocket/Packet ist UDP, da hast du nichtmal eine Garantie, dass überhaupt was beim Client ankommt :wink: 
Machs lieber so wie du es jetzt im anderen Thread geschrieben hast. Du kannst ja noch ein paar BufferedInput/OutputStreams drumhängen, damit das schneller geht.


----------



## Bleiglanz (26. Feb 2006)

stiewen hat gesagt.:
			
		

> Also, ich stürze mich jetzt einfach mal in die Klassen DatagrammSocket und DatagrammPacket rein
> Wer dies verhindern möchte, sollte bitte grund und andere lösung bereit stellen ...
> @bleiglanz: ich dachte, dass wenn einfach mal kein byte mehr gesendet wird oder der rest des buffers leer ist, ein -1 oder 0 überreicht wird... aber ich versuche das jetzt mit den beiden klassen zu umgehen



An deinem Problem ändert auch UDP nichts (ist übrigens der total falsche Weg, damit kannst du keine Datei übertragen)

"wenn einfach mal kein byte mehr gesendet wird oder der rest des buffers leer", das ist Wunschdenken...was soll das überhaupt heissen dass kein byte mehr gesendet wird...1 Sekunde lang nix? 10 Sekunden lang nix?? 100 Sekunden lang nix???

wie gesagt:

entweder eigenes Protokoll erfinden um das Ende zu erkennen

oder

close()


----------



## stiewen (26. Feb 2006)

KK, ich bleib beim streamen...
@Bleiglanz: ich übergebe im byte einfach ein -1 und fein is... oder geht das auch wieder net?

so, jetzt aber mal was komisches: ich hab mir die bytes eines jpg-Bildes mal einlesen lassen und mir ist was komisches aufgefallen. bei diesem Source:

```
FileInputStream fisIn = new FileInputStream(strFile);
      OutputStream osOut = soClient.getOutputStream();
      byte[] buffer = getBuffer();
      int intRead = 0;
      int intDelta;
      int intTemp = 0;
      while ( intRead < buffer.length ) {
        intDelta = fisIn.read(buffer, intRead, buffer.length - intRead);
        if ( intDelta == -1 )
          break;
        intRead += intDelta;
      }
      while ( intTemp < buffer.length ) {
        System.out.println(buffer[intTemp++] );
      }
```

und diesen buchstaben aus der datei: (jpg-bild mit editor öffnen)
ÿØÿà JF 
...

gibt er das aus:
-1
40

-1
-32
0
16
...
und dann noch ein paar negative zahlen, wie -2 und dann auch noch hier und da eine -1 ... WAS SOLL DAS DENN????
ich habe sie noch nicht mal gesendet und es kommen schon fehler


----------



## Beni (26. Feb 2006)

Hä? Der Editor versucht dein Bild als ASCII-Zeichen zu interpretieren, Java versucht es in signed bytes zu pressen. Die Darstellung ist doch total uninteressant, wichtig ist das Bitmuster, und das ist beidesmal identisch :wink:  Problematisch wird es erst, wenn du als signed byte liest, und als ASCII speicherst... wie man das mit den Reader/Writern machen kann.


----------



## Bleiglanz (27. Feb 2006)

> @Bleiglanz: ich übergebe im byte einfach ein -1 und fein is... oder geht das auch wieder net?


das ist ja ein Knüller, was ist wenn deine Datei mal zufällig eine -1 enthält

eine 2,3 MB mp3 hat knapp 2300000 Bytes, da könnte doch durchaus mal eine dabei sein


----------

