# Datei senden/empfangen funzt nicht...



## 1243sdf (1. Dez 2010)

Datei soll von Server zu Client geschickt werden.

Datei kommt zwar an, jedoch nur beschädigt mit 5 bytes (4KB sollte sie eigl. groß sein).

Danke!

Server:


```
public static void transferFile(File file, Socket client) {
        try {
            int b = 0;
            byte[] buffer = new byte[1024];
            OutputStream out = client.getOutputStream();

            FileInputStream fis = new FileInputStream(file);
            BufferedInputStream bis = new BufferedInputStream(fis);
            DataInputStream dis = new DataInputStream(bis);

            while (b != -1) {
                b = dis.read(buffer);

                out.write(b);
                out.flush();
            }
        }
        catch (FileNotFoundException exc) {
            exc.printStackTrace();
        }
        catch (IOException exc) {
            exc.printStackTrace();
        }
    }
```

Client:


```
public static void receiveFileFromServer(File targetFile) {

        try {
        InputStream in = Main.get().getSession().getConnection().getInputStream();
        FileOutputStream fileOut = new FileOutputStream(targetFile);

        byte[] buffer = new byte[1024];
        while (Main.get().getSession().getConnection().getSocket().isConnected()) {
            int bytesRead = in.read(buffer);
            if (bytesRead == -1) break;
            fileOut.write(buffer, 0, bytesRead);
        }

        fileOut.close();
        }
        catch (FileNotFoundException exc) {
            exc.printStackTrace();
        }
        catch (IOException exc) {
            exc.printStackTrace();
        }
    }
```


----------



## The_S (1. Dez 2010)

Du schickst beim Server den Rückgabewert von dis.read() und nicht den Puffer, in welchen du dis.read schreiben lässt.


----------



## adsfgwdaz (1. Dez 2010)

Nun scheint es ein wenig geklappt zu haben, jedoch nicht wirklich.

Nochmal zum Gesamtzusammenhang: In einer Chatsoftware soll der Server alle Avatare seiner Freunde an ihn schicken, damit sie in der Freundesliste dargestellt werden können.

Probleme:

1. Ich hab noch nie wirklich mit dem Versenden von Datein gearbeitet und versuche mich da durchzuhangeln.
2. Bild kommt an, jedoch laut Windows (7) Explorer mit 0 Bytes, das Thumbnail im Explorer funktioniert aber. Kann das Bild über die Windows-Bildanzeige auch ansehen, öffne ich es aber zb. mit Fireworks, meldet er mir einen Fehler. 
3. Führe ich diesen Vorgang (unten) pro Freund aus der Freundesliste aus, so empfange ich immer nur eins und die Bilder werden dann nicht ersetzt, sondern wachsen in der KB-Anzahl.


Zum Sachverhalt:

Client sendet an Server eine Nachricht, um ein Bild anzufordern.


```
try {
// Loginname and password is necessary for this action
                String loginname = Main.get().getSession().getUsername();
                String password = Main.get().getSession().getPassword();
                
                ClientUserPictureRequestMessage cuprm = new ClientUserPictureRequestMessage(loginname, password);
                cuprm.setOwner(username);
                
                Main.get().getSession().getConnection().getObjectOutputStream().writeObject(cuprm);
            }
            catch (java.io.IOException exc) {
                exc.printStackTrace();
            }
```

Server empfängt diese Nachricht, reagiert darauf und sendet eine Antwortnachricht und sendet dann das Bild.


```
public static void handleMessage(ClientMessage cm, ClientConnection cc) {
...
if (cm instanceof ClientUserPictureRequestMessage) {
                            ClientUserPictureRequestMessage cuprm = (ClientUserPictureRequestMessage) cm;
                            
                            if (UserManager.areFriends(cc.getUser(), UserManager.getDetailedUserByName(cuprm.getOwner()))) {
                                DetailedUser user = UserManager.getDetailedUserByName(cuprm.getOwner());

                                ServerUserPictureAnswerMessage supam = new ServerUserPictureAnswerMessage();
                                supam.setUsername(user.getUsername());

                                if (user.getUserPictureID() != null || user.getUserPictureID().equals("")) {
                                    // Settings
                                    supam.setUseDefaultPicture(false);
                                    supam.setSuccess(true);

                                    // Send answer object
                                    cc.getObjectOutputStream().writeObject(supam);

                                    // Send user picture
                                    File userPicture = new File(Main.get().getAppdataPath().getAbsolutePath() + "\\userPics\\" + user.getId() + ".png");
                                    FileTransferManager.transferFile(userPicture, cc.getSocket());
                                }
                                else {
                                    // Settings
                                    supam.setUseDefaultPicture(false);
                                    supam.setSuccess(true);

                                    // Send answer object
                                    cc.getObjectOutputStream().writeObject(supam);
                                }
                            }
                            else {
                                ServerUserPictureAnswerMessage supam = new ServerUserPictureAnswerMessage();
                                supam.setSuccess(false);

                                cc.getObjectOutputStream().writeObject(supam);
                            }
                        }
...
}
```

So wird das Bild gesendet:


```
public class FileTransferManager {

    public static void transferFile(File file, Socket client) {
        try {
            int bytesRead = 0;
            byte[] buffer = new byte[1024];
            OutputStream out = client.getOutputStream();

            FileInputStream fis = new FileInputStream(file);
            BufferedInputStream bis = new BufferedInputStream(fis);
            DataInputStream dis = new DataInputStream(bis);

            while (bytesRead != -1) {
                bytesRead = dis.read(buffer);

                if (bytesRead != -1) {
                    out.write(buffer, 0, bytesRead);
                    out.flush();
                }
            }
        }
        catch (FileNotFoundException exc) {
            exc.printStackTrace();
        }
        catch (IOException exc) {
            exc.printStackTrace();
        }
    }
}
```

Dann empfängt der Client die Nachricht:


```
if (sm instanceof ServerUserPictureAnswerMessage) {
            ServerUserPictureAnswerMessage message = (ServerUserPictureAnswerMessage) sm;

            if (!message.isUsingDefaultPicture()) {
                File userPictureFile = new File(Main.get().getAppdataPath().getAbsolutePath() + "\\userPics\\" + message.getUsername() + "." + message.getExtension());
                userPictureFile.delete();
                FileTransferManager.receiveFileFromServer(userPictureFile);
            }
        }
```

Und so wird dann das Bild empfangen:


```
public class FileTransferManager {

    public static void receiveFileFromServer(File targetFile) {

        try {
            InputStream in = Main.get().getSession().getConnection().getInputStream();
            FileOutputStream fileOut = new FileOutputStream(targetFile);

            byte[] buffer = new byte[1024];
            while (Main.get().getSession().getConnection().getSocket().isConnected()) {
                int bytesRead = in.read(buffer);
                if (bytesRead == -1) break;
                fileOut.write(buffer, 0, bytesRead);
            }

            fileOut.close();
        }
        catch (FileNotFoundException exc) {
            exc.printStackTrace();
        }
        catch (IOException exc) {
            exc.printStackTrace();
        }
    }
}
```


----------



## The_S (2. Dez 2010)

adsfgwdaz hat gesagt.:


> Zum Sachverhalt:
> 
> Client sendet an Server eine Nachricht, um ein Bild anzufordern.
> 
> ...



Dein Dateitransfer schaut erst einmal soweit OK aus. Konnte  zumindest beim drüberschauen auf die schnelle nichts falsches sehen (außer evtl. ein paar recht umständliche Codezeilen, die aber trotzdem funktionieren sollten). Könnte es sein, dass dein Fehler deshalb wo anders, bspw. in den von mir zitierten Codestellen liegt? Da ich deine ganzen Objekte und Klassen nicht kenne, kann ich nicht sagen, ob da oben was schief läuft oder nicht.



adsfgwdaz hat gesagt.:


> 1. Ich hab noch nie wirklich mit dem Versenden von Datein gearbeitet und versuche mich da durchzuhangeln.
> 2. Bild kommt an, jedoch laut Windows (7) Explorer mit 0 Bytes, das Thumbnail im Explorer funktioniert aber. Kann das Bild über die Windows-Bildanzeige auch ansehen, öffne ich es aber zb. mit Fireworks, meldet er mir einen Fehler.
> 3. Führe ich diesen Vorgang (unten) pro Freund aus der Freundesliste aus, so empfange ich immer nur eins und die Bilder werden dann nicht ersetzt, sondern wachsen in der KB-Anzahl.



1. Aller Anfang ist schwer
2. Schickst du evtl. in einem Format und speicherst in einem anderen? Überschreibst du die Bilder gleich wieder? Hast du mal "in das Bild" geguckt, ob wirklich 0 Bytes drinstehen? Der Fehler wäre natürlich auch interessant.
3. Dann übergibst du wohl immer wieder den selben Dateinamen als Ziel bzw. schickst du die Datei so, so dass der Empfänger das alles als "Ein Bild" interpretiert. Könnte auch sein, dass hiermit dein anderer Fehler zusammenhängt.


----------



## HoaX (2. Dez 2010)

Ich würde sagen dein Fehler liegt da, dass du beim Empfangen der Bilder auf -1 wartest beim read. Dieser Fall tritt erst dann auf die Verbindung getrennt wird, nicht dann, wenn die Gegenstelle nichts mehr zu senden hat (für den Augenblick). Darum landen dann auch alle Bilder in einer Datei.


----------



## The_S (2. Dez 2010)

HoaX hat gesagt.:


> Ich würde sagen dein Fehler liegt da, dass du beim Empfangen der Bilder auf -1 wartest beim read. Dieser Fall tritt erst dann auf die Verbindung getrennt wird, nicht dann, wenn die Gegenstelle nichts mehr zu senden hat (für den Augenblick). Darum landen dann auch alle Bilder in einer Datei.



Stmmt, das hatte ich übersehen.


----------

