tutorials.de Buch-Aktion 02/2012
Seite 1 von 2 12 LetzteLetzte
ERLEDIGT
JA
ANTWORTEN
24
ZUGRIFFE
15438
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Registriert seit
    Oct 2003
    Ort
    Erde
    Beiträge
    284
    Hi,
    Ich möchte eine Datei die bereits als File Objekt vorliegt mittels TCP (nicht UDP!) auf einen anderen Rechner übertragen.
    Ich hab zwar schon ein bischen mit den Sockets herumexperimentiert aber wenn ich mal was verschicken konnte dann kam die Datei unvollständig oder verstümmelt an.

    Habe gedacht das Dateiverschicken wäre eine Standardaufgabe und es gäbe vielleicht auch einen Standardcode dazu. In Büchern und im Web hab ich bisher allerdings nur wenig für mich verständliche Hilfe gefunden.

    Hat vielleicht jemand ein Codebeispiel für einen DateiServer und einem passenden Client zum empfangen?
     
    for all resources, whatever it is, you need more.
    [RFC 1925: The Twelve Networking Truths]
    www.thenbp.de

  2. #2
    Registriert seit
    Dec 2001
    Ort
    Bayern
    Beiträge
    5.774
    Blog-Einträge
    5
    Hallo!

    Datei senden:
    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    OutputStream out = socket.getOutputStream();
    InputStream fileIn = new FileInputStream(file);
     
    byte[] buffer = new byte[1024];
    while (fileIn.available() > 0) {
        out.write(buffer, 0, fileIn.read(buffer));
    }
     
    fileIn.close();

    Datei empfangen:
    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    InputStream in = socket.getInputStream();
    FileOutputStream fileOut = new FileOutputStream("dateiname.ext");
                
    byte[] buffer = new byte[1024];
    while (socket.isConnected()) {
        int bytesRead = in.read(buffer);
        if (bytesRead == -1) break;
        fileOut.write(buffer, 0, bytesRead);
    }
     
    fileOut.close();

    Grüße,
    Matthias
    Lastlord bedankt sich. 
    „Gib einem Menschen einen Fisch, und er wird für einen Tag satt. Lehre ihn Fischen, und er wird ein Leben lang satt.“
    “For every complex problem, there is an answer that is short, simple and wrong.”
    “Pessimism is safe, but optimism is a lot faster!”


    Aktuelles Coding Quiz: #17 - Wörter kreuz und quer

  3. #3
    Registriert seit
    Jun 2002
    Ort
    Saarbrücken (Saarland)
    Beiträge
    9.724
    Blog-Einträge
    29
    Hallo!

    Also ich wuerde das ganz Straight forward machen:
    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    
    /**
     * 
     */
    package de.tutorials;
     
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
     
    /**
     * @author Tom
     * 
     */
    public class TCPFileExchange {
     
        /**
         * @param args
         */
        public static void main(String[] args) {
            File file = new File("c:/bigfile-1.0.0.tgz");
            FileProvider fileProvider = new FileProvider(file, 4711);
            FileFetcher fileFetcher = new FileFetcher("localhost", 4711, file
                    .getName());
            ExecutorService executorService = Executors.newFixedThreadPool(2);
            executorService.execute(fileProvider);
            executorService.execute(fileFetcher);
            executorService.shutdown();
        }
     
        static class FileProvider implements Runnable {
     
            final File file;
     
            final int port;
     
            public FileProvider(File file, int port) {
                this.file = file;
                this.port = port;
            }
     
            public void run() {
                try {
                    System.out.println(getClass() + " Providing file...");
     
                    ServerSocket serverSocket = new ServerSocket(this.port);
                    Socket socket = serverSocket.accept();
     
                    System.out.println(getClass() + " sending file to: "
                            + socket.getRemoteSocketAddress());
     
                    byte[] buffer = new byte[16384];
                    InputStream inputStream = new FileInputStream(this.file);
                    OutputStream outputStream = socket.getOutputStream();
                    int len = 0;
                    while ((len = inputStream.read(buffer)) > 0) {
                        outputStream.write(buffer, 0, len);
                    }
     
                    System.out.println(getClass() + " sending completed");
                    inputStream.close();
                    outputStream.close();
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
     
        static class FileFetcher implements Runnable {
     
            String serverName;
     
            int port;
     
            String fileName;
     
            public FileFetcher(String serverName, int port, String fileName) {
                this.serverName = serverName;
                this.port = port;
                this.fileName = fileName;
            }
     
            public void run() {
                try {
                    Socket socket = new Socket(this.serverName, this.port);
                    File file = new File(
                            System.getProperty("java.io.tmpdir"),
                            fileName);
                    System.out.println(getClass() + " Fetching file... " + file);
                    OutputStream outputStream = new FileOutputStream(file);
                    InputStream inputStream = socket.getInputStream();
     
                    byte[] buffer = new byte[16384];
                    int len = 0;
                    while ((len = inputStream.read(buffer)) > 0) {
                        outputStream.write(buffer, 0, len);
                    }
                    System.out.println(getClass() + " Fetching complete.");
                    outputStream.close();
                    inputStream.close();
                    socket.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    Gruss Tom
    KOKser bedankt sich. 
    Java rocks!
    How to become a good Java Programmer?
    Does IT in Java and .Net
    The only valid measurement of code quality: WTFs / minute
    Blog
    Xing
    Twitter

  4. #4
    Registriert seit
    Oct 2003
    Ort
    Erde
    Beiträge
    284
    Funktioniert einwandfrei, Danke!
     
    for all resources, whatever it is, you need more.
    [RFC 1925: The Twelve Networking Truths]
    www.thenbp.de

  5. #5
    Rocco1979 Rocco1979 ist offline Grünschnabel
    Registriert seit
    Nov 2007
    Beiträge
    2
    Hi,



    Frage:
    wie kommt man auf die Byte grösse? kann man immer diese im Beispiel verwenden?


    Gruss
     

  6. #6
    EGJ-Soldier EGJ-Soldier ist offline Mitglied Bronze
    Registriert seit
    Jul 2008
    Beiträge
    45
    Hallo zusammen,
    Das Programm von Thomas funktioniert bei mir ebenfalls tadellos, jodoch habe ich ein paar fragen, dazu unzwar:

    1. Wie kann ich die IP-ändern,
    2. Wie kann ich die Portnummer ändern,
    3. Wie kann ich eine bestimmte Dateien Laden z.B: D:\Ordner\Ordner\Java.jar und
    4. Wie kann ich dem Programm sagen, in welchen Ordner er das Dokument beim anderen Rechner abspeichern soll.

    Ich bin mit meinem Latein am Ende , deswegen bitte ich um Hilfe

    Ich danke schonmal im Voraus
    EGJ-Soldier
     

  7. #7
    Avatar von takidoso
    takidoso takidoso ist offline Mitglied Brillant
    Registriert seit
    Aug 2004
    Ort
    Kömigstein
    Beiträge
    905
    Zitat Zitat von Rocco1979 Beitrag anzeigen
    Hi,



    Frage:
    wie kommt man auf die Byte grösse? kann man immer diese im Beispiel verwenden?


    Gruss
    Nicht das ich das jetzt nachgeprüft hätte,
    aber es wird, so vermute ich mal die nächste binäre ermittelte Zahl von der Zielgröße 16000 sein.
    also binär 100000000000000 = deimal 16384
    und binär 10000000000 = 1024
    Warum man sich da solcher Zahlen bedient würde ich so spekulieren, dass vielleicht der verwendete Platz das potential der Codierung möglicherweise besser ausnutzt. aber wie gesagt ist das nu rSpekulation meinerseits.
    @ Tom, gibt es da tatsächlichen einen optimierenden Zusammenhang bezüglich JVM, oder ist das nur um sich an binären Zahlengrößen traditionsbewußt zu orientieren?

    mit neugierigen Grüßen

    Takidoso
     

  8. #8
    EGJ-Soldier EGJ-Soldier ist offline Mitglied Bronze
    Registriert seit
    Jul 2008
    Beiträge
    45
    Guten Tag ich bin es noch mal,
    kann mir echt niemand bei meinen Fragen helfen, es wäre nämlich sehr nett, da ich ein Projekt fertigstellen muss und natürlich die bestmögliche Note ereichen will

    ich ware ich für jede Hilfe dankbar

    gruß EGJ-Soldier
     

  9. #9
    Avatar von takidoso
    takidoso takidoso ist offline Mitglied Brillant
    Registriert seit
    Aug 2004
    Ort
    Kömigstein
    Beiträge
    905
    Zitat Zitat von EGJ-Soldier Beitrag anzeigen
    Guten Tag ich bin es noch mal,
    kann mir echt niemand bei meinen Fragen helfen, es wäre nämlich sehr nett, da ich ein Projekt fertigstellen muss und natürlich die bestmögliche Note ereichen will

    ich ware ich für jede Hilfe dankbar

    gruß EGJ-Soldier
    Also ich denke da ist lediglich Phantasie gefragt, oder?
    ad 1) & 2) IP und Port kannst Du doch ändern indem Du lediglich einen anderen Port übergibst. Man kann dies zum Beispiel mit einer Properties-Datei bewerkstelligen.
    aus 3 und 4 stellt sich bei mir die Frage wie Du das fachlich haben willst. Soll der Client aussuchen können welche Datei er wählt odersoll der Server bestimmten welche Datei er sendet?
    Wenn der Client auswhlt und gleichzeitig die "variable" sein soll wäre es vielleicht sinnvoll, wenn er weiß was er beim Server runterladen kann. Man könnte sowas mit einem eigenen Protokoll basteln. Vielleicht hilft Dir das ja weiter:
    http://java.seite.net/chat/sockets.html
    Geändert von takidoso (15.07.08 um 11:38 Uhr)
     

  10. #10
    EGJ-Soldier EGJ-Soldier ist offline Mitglied Bronze
    Registriert seit
    Jul 2008
    Beiträge
    45
    Guten Tag
    ich bin kein so großer Java-kenner, desswegen stelle ich diese Fragen.

    Zu Frage 1 und 2: Ich finde im Quelltext nirgends die Stelle in der die IP und der Port definiert sind. Die Zeile wo steht this.port = port sagt mir da nicht viel. Wenn ich das Programm laufen lassen will, versucht er immer auf den localhost zuzugreifen und immer auf einen bestimmten Port.
    Zu Frage 3 und 4: Ich möchte, dass der Server wählt (indemfall mein rechner), welche datei er verschickt. Er soll sie dann bei einem anderen Rechner in einen bestimmten Ordner legen.

    Ich fände es echt nett, wenn ihr mir noch weiterhelfen könnt. Wie gesagt, in Java kenne ich nur die grundkenntnisse und verstehe nicht sehr viel von Netzwerkprogrammierung

    gruß
    EGJ-Soldier
     

  11. #11
    Avatar von takidoso
    takidoso takidoso ist offline Mitglied Brillant
    Registriert seit
    Aug 2004
    Ort
    Kömigstein
    Beiträge
    905
    Zitat Zitat von EGJ-Soldier Beitrag anzeigen
    Guten Tag
    ich bin kein so großer Java-kenner, desswegen stelle ich diese Fragen.

    Zu Frage 1 und 2: Ich finde im Quelltext nirgends die Stelle in der die IP und der Port definiert sind. Die Zeile wo steht this.port = port sagt mir da nicht viel. Wenn ich das Programm laufen lassen will, versucht er immer auf den localhost zuzugreifen und immer auf einen bestimmten Port.
    Zu Frage 3 und 4: Ich möchte, dass der Server wählt (indemfall mein rechner), welche datei er verschickt. Er soll sie dann bei einem anderen Rechner in einen bestimmten Ordner legen.

    Ich fände es echt nett, wenn ihr mir noch weiterhelfen könnt. Wie gesagt, in Java kenne ich nur die grundkenntnisse und verstehe nicht sehr viel von Netzwerkprogrammierung

    gruß
    EGJ-Soldier
    Also zunächst mal wäre es sicher von Vorteil für Dich tiefer als bisher in Java einzusteigen.
    Du hast im Grunde schon die richtige Zeile bezüglich Port rausgefunden. this.port=port bedeutet überweise der Member-Variable port den inhalt von der lokale Variable (in diesem Fall Parameter) port. Wenn Du gerade mal eine Zeile darüber schaust siehst Du dass dort die Member-Variable port definiert ist.

    Zum Thema 3 & 4 ist im Gunde nur Phantasie gefragt. Man könnte der Einfachheit wegen z.B. alles hard codeieren, dass der Server fest den Dateinamen in sich integriert hat, und das Ziel wohin dem Client überlassen wird, was ebenfalls der Einfacheit halber hart codiert werden könnte. Wenn Du es ein bissel weicher haben willst würde ich empfehlen diese Kerninformationen (Quelldateiname auf Seiten des Servers, und Zieldateipfad auf Seiten des Clients in jeweilige Properties-Dateien zu speichern und bei Bedarf zu lesen.
    Bitte erwarte hier keinen Code von mir, es wäre Dir mehr von Nutzen Dir selbst detailiertere Gedanken zu machen und Dich dadurch auch in Sachen Java sicherer zu machen.

    viel Spaß

    Takidoso
    Geändert von takidoso (16.07.08 um 16:47 Uhr)
     

  12. #12
    EGJ-Soldier EGJ-Soldier ist offline Mitglied Bronze
    Registriert seit
    Jul 2008
    Beiträge
    45
    Ich bedanke mich für deine hilfe und werde mir deinen rat zu Herzen nehmen
    (Ich werde mich was tiefer mit Java beschäftigen)

    Gruß
    EGJ-Soldier
     

  13. #13
    Registriert seit
    Jun 2002
    Ort
    Saarbrücken (Saarland)
    Beiträge
    9.724
    Blog-Einträge
    29
    Hallo,

    hier mal noch nachträglich eine etwas schneller NIO Variante:
    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    
    /**
     * 
     */
    package de.tutorials;
     
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.net.Socket;
    import java.nio.channels.FileChannel;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
     
    /**
     * @author Tom
     * 
     */
    public class TCPFileExchange {
     
        /**
         * @param args
         */
        public static void main(String[] args) {
            File file = new File("D:/VMWare/40g xp development/xp-s005.vmdk");
            FileProvider fileProvider = new FileProvider(file, 4711);
     
            FileFetcher fileFetcher = new FileFetcher("localhost", 4711);
            ExecutorService executorService = Executors.newFixedThreadPool(2);
            executorService.execute(fileProvider);
            executorService.execute(fileFetcher);
     
            executorService.shutdown();
        }
     
        static class FileProvider implements Runnable {
     
            final File file;
     
            final int port;
     
            public FileProvider(File file, int port) {
                this.file = file;
                this.port = port;
            }
     
            public void run() {
                try {
                    System.out.println(getClass() + " Providing file...");
     
                    ServerSocketChannel serverSocketChannel = ServerSocketChannel
                            .open();
                    serverSocketChannel.socket().bind(new InetSocketAddress(port));
                    SocketChannel socketChannel = serverSocketChannel.accept();
                    Socket socket = socketChannel.socket();
     
                    FileInputStream fileInputStream = new FileInputStream(this.file);
                    DataOutputStream dataOutputStream = new DataOutputStream(socket
                            .getOutputStream());
                    dataOutputStream.writeUTF(file.getName());
                    dataOutputStream.writeLong(file.length());
     
                    dataOutputStream.flush();
     
                    FileChannel fileChannel = fileInputStream.getChannel();
     
                    transfer(fileChannel, socketChannel, file.length(),
                            1024 * 1024 * 16, true, true);
     
                    fileInputStream.close();
     
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
     
        static class FileFetcher implements Runnable {
     
            String serverName;
     
            int port;
     
            public FileFetcher(String serverName, int port) {
                this.serverName = serverName;
                this.port = port;
            }
     
            public void run() {
                try {
                    SocketChannel socketChannel = SocketChannel
                            .open(new InetSocketAddress(serverName, port));
                    Socket socket = socketChannel.socket();
     
                    DataInputStream dataInputStream = new DataInputStream(socket
                            .getInputStream());
                    String fileName = dataInputStream.readUTF();
                    long sizeInBytes = dataInputStream.readLong();
     
                    System.out.println("FileSize: " + sizeInBytes);
     
                    File file = new File("c:/temp", "x_" + fileName);
                    System.out.println(getClass() + " Fetching file... " + file);
                    FileOutputStream fileOutputStream = new FileOutputStream(file);
                    FileChannel fileChannel = fileOutputStream.getChannel();
     
                    transfer(fileChannel, socketChannel, sizeInBytes,
                            1024 * 1024 * 16, true, false);
     
                    fileOutputStream.close();
                    socket.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
     
        public static void transfer(FileChannel fileChannel,
                SocketChannel socketChannel, long lengthInBytes,
                long chunckSizeInBytes, boolean verbose, boolean fromFileToSocket)
                throws IOException {
     
            long overallBytesTransfered = 0L;
            long time = -System.currentTimeMillis();
            while (overallBytesTransfered < lengthInBytes) {
     
                long bytesTransfered = 0L;
     
                if (fromFileToSocket) {
                  bytesTransfered = fileChannel.transferTo(overallBytesTransfered, Math.min(
                            chunckSizeInBytes, lengthInBytes
                                    - overallBytesTransfered), socketChannel);
                } else {
                    bytesTransfered = fileChannel.transferFrom(socketChannel,
                            overallBytesTransfered, Math.min(chunckSizeInBytes,
                                    lengthInBytes - overallBytesTransfered));
                }
     
                overallBytesTransfered += bytesTransfered;
     
                if (verbose) {
                    System.out.printf(
                            "overall bytes transfered: %s progress %s%%\n",
                            overallBytesTransfered, Math
                                    .round(overallBytesTransfered
                                            / ((double) lengthInBytes) * 100.0));
                }
     
            }
            time += System.currentTimeMillis();
     
            if (verbose) {
                System.out.printf("Transfered: %s bytes in: %s s -> %s kbytes/s",
                        overallBytesTransfered, time / 1000,
                        (overallBytesTransfered / 1024.0) / (time / 1000.0));
            }
     
        }
     
    }

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    class de.tutorials.TCPFileExchange$FileProvider Providing file...
    overall bytes transfered: 16777216 progress 1%
    overall bytes transfered: 33554432 progress 2%
    overall bytes transfered: 50331648 progress 2%
    overall bytes transfered: 67108864 progress 3%
    overall bytes transfered: 83886080 progress 4%
    overall bytes transfered: 100663296 progress 5%
    overall bytes transfered: 117440512 progress 5%
    ...
    overall bytes transfered: 2097152000 progress 98%
    overall bytes transfered: 2113929216 progress 99%
    overall bytes transfered: 2130706432 progress 99%
    overall bytes transfered: 2143158272 progress 100%
    Transfered: 2143158272 bytes in: 189 s -> 11036.612439686767 kbytes/s
    Hiermit braucht man für 2gb knapp 3 Minuten (bei 2 verschiedenen Rechnern über 100 MBit Netzwerkkarten verbunden)

    Gruß Tom
    KOKser und Lastlord bedanken sich. 
    Java rocks!
    How to become a good Java Programmer?
    Does IT in Java and .Net
    The only valid measurement of code quality: WTFs / minute
    Blog
    Xing
    Twitter

  14. #14
    na3r0n na3r0n ist offline Grünschnabel
    Registriert seit
    Dec 2009
    Beiträge
    1
    Entschuldigung, dass ich hier ein so altes Thema ausgrabe, aber ich versuche gerade ebenfalls per tcp eine Datei zu übertragen in Java. Die Methode von Thomas gefällt mir ganz gut und ist auch recht schnell. Allerdings werden die Dateien nicht korrekt übertragen, sobald die Dateigröße die Buffergröße überschreitet. Daher würde es mich interessieren, ob es nicht eine Möglichkeit gibt, dafür zu sorgen, die Datenpakete geordnet aufzufangen oder ob vielleicht ein anderer Grund das Problem ist.
     

  15. #15
    david-java Tutorials.de Gastzugang
    Der Fehler liegt in Zeile 136, es muss heissen:

    Code :
    1
    2
    3
    
    bytesTransfered = fileChannel.transferTo(overallBytesTransferred, Math.min(
                            chunckSizeInBytes, lengthInBytes
                                    - overallBytesTransfered), socketChannel);

    Sonst beginnt die Datei immer wieder bei 0 zu schreiben.

    Gruss david
     

Ähnliche Themen

  1. TXT-Datei an PHP-Datei per HTTP übertragen.
    Von WorldRacer im Forum .NET Web und Kommunikation
    Antworten: 3
    Letzter Beitrag: 27.08.09, 16:05
  2. [AJAX mittels XML] Geschütztes Leerzeichen übertragen
    Von Thomas D im Forum Javascript & Ajax
    Antworten: 1
    Letzter Beitrag: 03.03.08, 17:31
  3. Datei übertragen per RMI
    Von Moltar im Forum Java
    Antworten: 2
    Letzter Beitrag: 24.04.07, 16:25
  4. Antworten: 8
    Letzter Beitrag: 21.07.05, 09:40
  5. Antworten: 4
    Letzter Beitrag: 01.08.04, 13:55