2010-12-08 8 views
1

ich eine Java-Server-Klasse wie dieses:Übertragung Sockel eine Datei

ServerSocket servsock = new ServerSocket(63456); 
boolean read = false; 
while (!read) { 
    Socket sock = servsock.accept(); 
    int length = 1024; 
    byte[] mybytearray = new byte[length]; 
    OutputStream os = sock.getOutputStream(); 
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myFile)); 
    while (true) { 
    int i = bis.read(mybytearray, 0, mybytearray.length); 
    if (i == 1) { 
     break; 
    } 
    os.write(mybytearray, 0, mybytearray.length); 
    os.flush(); 
    } 
    sock.close(); 
    read = true; 
} 

` Und der Kunde ist wie folgt:

Socket sock = new Socket("127.0.0.1", 63456); 
byte[] mybytearray = new byte[1024]; 
InputStream is = sock.getInputStream(); 
FileOutputStream fos = new FileOutputStream("C:/tmp/NEWtmp.rar"); 
BufferedOutputStream bos = new BufferedOutputStream(fos); 
int bytesRead = is.read(mybytearray, 0, mybytearray.length); 
while(bytesRead != -1) { 
    bos.write(mybytearray, 0, bytesRead); 
    bytesRead = is.read(mybytearray, 0, mybytearray.length); 
} 
bos.close(); 
sock.close(); 

Eine Frage ist: Warum die Schleife nicht aufhört das Ende der Datei? Eine zweite Frage wäre, warum ist auch so langsam?

Antwort

4

Es hört nicht auf, weil

if (i == 1) { 

in der Server-Quelle

if (i == -1) { 

Oder sein sollte, wenn Sie wirklich sicher sein wollen:

if (i <= 0) { 

auch das Risiko, Sie Datenkorruption mit dieser Zeile:

os.write(mybytearray, 0, mybytearray.length); 

sollten Sie dies ändern:

os.write(mybytearray, 0, i); 

Auf Leistung - bewegen Sie den os.flush(); Anruf außerhalb der while Schleife. Wenn Sie einen Netzwerkstream leeren, müssen Sie alle gepufferten Daten an das Netzwerk senden. Dies zwingt die Netzwerkschicht zum Senden und Bestätigen von 1024-Byte-TCP-Nutzdaten (natürlich größere Ethernet-Nutzlasten), die wahrscheinlich wesentlich kleiner als Ihre PMTU sind. Sie müssen nur spülen, wenn Sie mit dem Senden von Daten fertig sind oder wenn der Client die gepufferten Daten jetzt empfangen soll. Durch Entfernen des Flush-Aufrufs aus jeder Iteration kann der Netzwerkpuffer auf Betriebssystemebene seine Aufgabe erfüllen und die Daten in so wenige Pakete wie möglich segmentieren.

+0

Danke, es hat funktioniert! – hephestos

2

Zweite Frage - Ihr Client liest Bytes direkt aus dem Raw-Socket-Stream. Verwenden Sie die BufferedInputStream/BufferedOutputStream Dekorateure, sollte dies die Leistung steigern:

Server Side

BufferedOutputStream os = new BufferedOutputStream(sock.getOutputStream()); 

Client-Seite

BufferedInputStream is = new BufferedInputStream(sock.getInputStream()); 

Die Ausgangsströme werden nicht gepuffert (AFAIK), so haben Sie um die Pufferung bei Bedarf manuell hinzuzufügen.

+0

Ja, das hat etwas Geschwindigkeit hinzugefügt. Es war so einfach ;-) Ich hätte es selbst sehen sollen, auf jeden Fall danke. – hephestos