2012-04-13 3 views
2

Ich habe versucht, eine große Datei über eine Socket Verbindung zu senden, aber es läuft langsam und ich frage mich, ob dieser Code in irgendeiner Weise optimiert werden kann die Übertragungsgeschwindigkeit.Übertragung einer Datei über ein Netzwerk mit TCP (Beschleunigung der Übertragung)

Dies ist mein Code für das Senden der Datei:

byte[] buffer = new byte[65536]; 
int number; 

while ((number = fileInputStream.read(buffer)) != -1) { 
    socketOutputStream.write(buffer, 0, number); 
} 

socketOutputStream.close(); 
fileInputStream.close(); 

Dies ist, was ich verwenden, um die Datei auf der anderen Maschine zu erhalten:

byte[] buffer = new byte[65536]; 

InputStream socketStream= clientSocket.getInputStream(); 
File f=new File("C:\\output.dat"); 

OutputStream fileStream=new FileOutputStream(f); 

while ((number = socketStream.read(buffer)) != -1) { 
    fileStream.write(buffer,0,number); 
} 

fileStream.close(); 
socketStream.close(); 

ich das Filestream denken Schreiben wird die Einnahme die meiste Zeit. Könnte irgendjemand irgendeinen Rat geben, diesen Code zu beschleunigen?

Antwort

5

Es ist nichts offensichtlich falsch mit diesem Code, außer dem Fehlen von finally Blöcke für die close Aussagen.

Wie lange dauert es für wie viele Daten? Es ist sehr unwahrscheinlich, dass die die Zeit braucht - es ist viel wahrscheinlicher, dass das Netzwerk langsam ist. Sie könnte potenziell aus dem Netzwerk lesen und parallel zum Dateisystem schreiben, aber das wäre eine Menge Arbeit, um richtig zu kommen, und es ist unwahrscheinlich, dass so viel Nutzen, IMO geben.

+0

Sie haben Recht. Ich konnte in 1111s ungefähr 1327582120 Bytes übertragen. Die Anweisung fileOutputStream.read (..) nahm insgesamt ungefähr 7 Sekunden in Anspruch, was angesichts der Größe der Datei ziemlich normal zu sein scheint. Das Problem war tatsächlich mit dem Netzwerk, das mir verschiedene Übertragungsraten gab (ich habe viele PCs mit diesem Netzwerk verbunden). Aber gibt es in diesem Code noch Verbesserungsmöglichkeiten? :) Tools wie IPMSG geben mir konsistente Übertragungsraten, die etwas besser sind als das, was ich hier bekommen habe, und so fragte ich mich, ob es mein schlechter Code war, der das Problem verursachte. – coderplus

+0

@aneesh: Man muss ziemlich genau schauen, was auf der Netzwerkebene vor sich geht - aber ich vermute, dass man * signifikante * zusätzliche Komplexität für nur einen * leichten * Leistungszuwachs benötigt. Allerdings scheint 1MB/Sekunde nicht besonders schnell zu sein - auf welcher Art von Netzwerk ist das? –

+0

kein verdrahtetes. Es ist ein WiFi-Netzwerk mit einem ADSL-Router – coderplus

1

Sie könnten einen BufferedOutputStream um den FileOutputStream versuchen. Es hätte den Effekt, alle Schreibvorgänge auf der Festplatte zu blockieren, unabhängig von der Anzahl, die Sie aus dem Netzwerk gelesen haben. Ich würde keinen großen Unterschied erwarten, aber es könnte ein bisschen helfen.

1

Ich hatte ein ähnliches Problem FTP'ing große Dateien. Ich erkannte, dass die Verwendung des gleichen Puffers für das Lesen von der Festplatte und das Schreiben in das Netzwerk das Problem war. Das Dateisystem IO mag größere Puffer, da es viel weniger Arbeit für die Festplatte gibt, das gesamte Suchen und Lesen durchzuführen. Netze andererseits bevorzugen dann kleinere Puffer zur Durchsatzoptimierung.

Die Lösung besteht darin, mit einem großen Puffer von der Festplatte zu lesen und diesen Puffer dann in kleineren Abschnitten in den Netzwerkstream zu schreiben.

Ich war in der Lage, meine NIC bei 100% Auslastung für die gesamte Länge von jeder Datei mit 4 MB liest und 32 KB schreiben. Sie können dann die gespiegelte Version auf dem Server machen, indem Sie jeweils 32kb einlesen und im Speicher abspeichern und dann 4mb gleichzeitig auf die Festplatte schreiben.