Buffergröße anpassen, aber wie?

  • Themenstarter Hans Guck In Die Luft
  • Beginndatum
Status
Nicht offen für weitere Antworten.
H

Hans Guck In Die Luft

Gast
Hallo,
ich habe einen Server und einen Client programmiert, die sich eine Datei zuschicken sollen. Wenn ich kleine Dateien benutze funktioniert das ganze auch. Bei größeren Dateien klappt es allerdings nicht. Ich glaube, dass das daran liegt, dass der letzte Buffer, der verschickt wird nicht, nicht vollständig gefüllt ist. Wie kann ich es hinbekommen, dass der letzte Buffer nur so groß ist, wie er auch sein muss? Bin für jede Antwort dankbar. Hier Quellcode von Server und Client...


SERVER:
Code:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.*;

public class FileTransferServer {

	DataInputStream dis = null; 
	  int b = 0;
	  byte[] schreib = new byte[1024];
	  String text = "";
	  DataOutputStream textstream;
	  
	  
	  private final ServerSocket server;
	  public FileTransferServer( int port ) throws IOException
	  {
	    server = new ServerSocket( port );
	    //server.setSoTimeout(60000); //60 Sekunden
	    
	  }
	  private void startServing()
	  {
	    while ( true )
	    {
	      Socket client = null;
	      try
	      {
	        client = server.accept();
	        handleConnection ( client );
	      }
	      catch ( IOException e ) {
	        e.printStackTrace();
	      }
	      finally {
	        if ( client != null )
	          try { client.close(); } catch ( IOException e ) { e.printStackTrace(); }
	      }
	    }
	  }
	  private void handleConnection( Socket client ) throws IOException
	  {
		    OutputStream out = client.getOutputStream();
		
	    try 
	    { 
	          b = 0;
	          File f = new File("C:/datei.exe"); 

	          FileInputStream fis = new FileInputStream(f); 
	          BufferedInputStream bis = new BufferedInputStream(fis); 
	          dis = new DataInputStream(bis);
	          
	          while ( b != -1 ) 
	          { 
	              
	               b = dis.read(schreib);
	         	  
	               out.write(schreib);
	               
	               out.flush();

	            }
	    }
	    
	    
	    catch (IOException e) 
	    { 
	       System.out.println("IO Excpetion: " + e.getMessage()); 
	    }
	    
	    finally
	    { 
	       if (dis != null)
	      { 
	    	   
	    	   try 
	    	   {
	    		   dis.close(); 
	    	   } 
	      
	    	   catch (IOException ioe)
	    	   {
	    	   }
	      
	       } 
	    }
	   
	  }
	
	  
	public static void main(String[] args) throws IOException {
		
		FileTransferServer server = new FileTransferServer( 3141 );
	    server.startServing();

	}

}


CLIENT:
Code:
import java.net.*;
import java.io.*;

class Client
{
  public static void main( String[] args )
  {
    int b=0;
    File nf = new File("D:/datei.exe");
    DataOutputStream dos;
    Socket server = null;
    byte[] les = new byte[1024];
    
    try
    {
    	
      InetAddress adresse = InetAddress.getByName("localhost");
    		
      server = new Socket(adresse , 3141 );
      InputStream in = server.getInputStream();
           
      FileOutputStream fos = new FileOutputStream(nf);
      BufferedOutputStream bos = new BufferedOutputStream(fos);
      dos = new DataOutputStream(bos);
      
while ( b != -1 ) { 
    	  
    	  b = in.read(les);
    	  
          dos.write(les);
          dos.flush();          

       }
      
    }
    catch ( UnknownHostException e ) {
      e.printStackTrace();
    }
    catch ( IOException e ) {
      e.printStackTrace();
    }
    finally
    {
      if ( server != null )
        try { server.close(); } catch ( IOException e ) { e.printStackTrace(); }
    }
  }
}
 
S

SlaterB

Gast
das Array ist ok, aber wenn es nicht voll gefüllt ist,
dann schreibe nur soviel davon wie gefüllt ist,
(sowohl beim Client als auch beim Servert)

die Information steckt in b


void write(byte[] b, int off, int len)
Writes len bytes from the specified byte array starting at offset off to this output stream.
 
G

Guest

Gast
Das hilft mir leider noch nicht so richtig weiter.
Kann mir jemand ein kleines Beispiel dazu geben?

Code:
while ( b != -1 ) { 
    	  
    	  b = in.read(les);
    	  
    	  if(b != 1024)
    	  {
    		  ??? 
    	  }
    	  
          dos.write(les, 0, b);
          dos.flush();

       }
      

    }

Wie genau krieg ich denn jetzt raus, wieviele von den 1024 gefüllt sind und wie schreibe ich das dann in einen neuen Buffer mit der entsprechenden Größe?
 
S

SlaterB

Gast
einfach nur
b = in.read(les);
dos.write(les, 0, b);


wenn am Ende nur noch 400 Daten da sind,
dann ist das Array zu 400 Bytes richtig und zu 624 Bytes mit alten Daten gefüllt,
b ist 400 und dos.write(les, 0, b); schreibt genau die verbleibenden 400 Daten,

evtl. solltest du noch abfangen, ob b genau in diesem Moment -1 ist,
aber wahrscheinlich kommt dos.write(les, 0, b); auch mit b = -1 klar (testen!)
 
S

SlaterB

Gast
das musst du doch nicht

> void write(byte[] b, int off, int len)
> Writes len bytes from the specified byte array starting at offset off to this output stream.

wenn len nur 400 ist, dann wird der hintere Teil des Arrays ignoriert
 
G

Guest

Gast
Aber die Datei scheint nicht richtig übertragen zu werden, weil ich sie nach der Übertragung nicht mehr ausführen kann. Hast Du eine Ahnung woran das dann liegt? Irgendwo muss doch dann im Code noch was falsch sein.
 
G

Guest

Gast
Die empfangene Datei ist immer größer als die gesendete Datei. Kann mir jemand sagen woran das liegt und wie ich das korrigieren kann?
 
S

SlaterB

Gast
wie gesagt muss du das sowohl beim Client als auch beim Server machen,
bei beiden werden Arrays befüllt und weitergereicht,

und wenns noch nicht hilft, dann fängt das Debugging an,
verwende ein Array der Länge 3, eine Datei der Länge 5 mit 5 unterschiedlichen Bytes/ chars 0, 1, 2, 3, 4

und dann schaue an allen Stellen der Übertragung was jeweils aus Sockets gelesen oder geschrieben wird,
die Array-Inhalte,
wie sieht die Finaldatei genau aus usw.

nur fragend davorstehen hat noch kein Problem gelöst :bae:
 
G

Guest

Gast
Ok, ich hab's geschafft. Die Datei wird richtig übertragen, aber ich bekomme trotzdem noch einige Fehlermeldungen ausgespuckt, mit denen ich nicht viel anfangen kann...

Beim Server:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at FileTransferServer.handleConnection(FileTransferServer.java:61)
at FileTransferServer.startServing(FileTransferServer.java:32)
at FileTransferServer.main(FileTransferServer.java:97)


Beim Client:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at java.io.BufferedOutputStream.write(Unknown Source)
at java.io.DataOutputStream.write(Unknown Source)
at Client.main(FileTransferClient.java:30)


Kann das jemand für mich interpretieren? :)
 
S

SlaterB

Gast
wie kann gleichzeitig eine Exception auftreten sowie die Datei korrekt übertragen werden?

schreibe an die jeweilige Stelle eine Debug-Ausgabe, welche Ausgabe kommt zuletzt vor der Exception?

System.out.println("schreibe Array der Länge x, mit b = b");
dos.write(les, 0, b);
System.out.println("Schreiben erfolgreich, Array der Länge x, mit b = b");
 
G

Guest

Gast
Hab ich gemacht...

Er schreibt jetzt zig mal das gleiche und nur in der Mitte irgendwo das hier...

Werd ich nicht schlau draus...


...vorher immer erfolgreich...

Schreiben erfolgreich, Array der Länge x, mit b = b
schreibe Array der Länge x, mit b = b
Schreiben erfolgreich, Array der Länge x, mit b = b
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at java.io.BufferedOutputStream.write(Unknown Source)
at java.io.DataOutputStream.write(Unknown Source)
at Client.main(FileTransferClient.java:30)
schreibe Array der Länge x, mit b = b
Schreiben erfolgreich, Array der Länge x, mit b = b
schreibe Array der Länge x, mit b = b
Schreiben erfolgreich, Array der Länge x, mit b = b


...nachher immer erfolgreich...
 
S

SlaterB

Gast
fange die Exception mit try catch ab und beende das Programm an dieser Stelle, und zu erkennen, wann genau es passiert:
System.out.println("ArrayIndexOutOfBoundsException ");
System.exit(0);

und du sollst keinen festen String ausgeben (was bringt das denn? ;) )
sondern die aktuelle Länge des Arrays und von b
 
G

Guest

Gast
Ok, beim Server endet das ganze jetzt so:

schreibe Array der Länge [B@7c6768 , mit b = 1024
Schreiben erfolgreich, Array der Länge 1024, mit b = [B@7c6768
schreibe Array der Länge [B@7c6768 , mit b = 1024
Schreiben erfolgreich, Array der Länge 1024, mit b = [B@7c6768
schreibe Array der Länge [B@7c6768 , mit b = 847
Schreiben erfolgreich, Array der Länge 847, mit b = [B@7c6768
schreibe Array der Länge [B@7c6768 , mit b = -1
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at FileTransferServer.handleConnection(FileTransferServer.java:61)
at FileTransferServer.startServing(FileTransferServer.java:32)
at FileTransferServer.main(FileTransferServer.java:97)


Das würde bedeuten, dass er ein Problem mit der -1 hat, oder lieg ich da falsch?
 
S

SlaterB

Gast
und bei -1 musst du ja nicht mehr unbedingt schreiben,
also leicht zu lösen

die Länge eines Arrays bekommt man übrigens mit array.length
 
G

Guest

Gast
Ich habe ja in meinem Quelltext stehen " while (b !=1) ".
Warum führt der das dann trotzdem nochmal aus?
 
G

Guest

Gast
Hat sich schon erledigt. Hab noch eine if-Verzweigung wegen dem -1 eingebaut und jetzt geht's.
Vielen Dank für Deine Hilfe und Deine Geduld. :)
 
S

SlaterB

Gast
.........



while ( b != -1 ) // hier b ganz bestimmt nicht -1
{

b = dis.read(schreib); // hier b vielleicht -1

write(array,0,b); // wer soll bitte verhindern, dass b hier -1 ist?
}


einmal nachdenken sollte doch drin sein
 
G

Guest

Gast
Ja, hab ich dann auch gesehen. War ne blöde Frage. Also es geht jetzt. Vieeelen Dank. :)
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
I HTTP Datei Uploaden mit http und Sprache anpassen Netzwerkprogrammierung 7
S .jar läuft local, aber nicht remote (SSH/Terminal) Netzwerkprogrammierung 10
D Verbindung zu Geräten mit gleicher IP aber in unterschiedlichen VLans aufbauen Netzwerkprogrammierung 2
V TCP Client funktioniert auf Emulator aber nicht auf Smartphone Netzwerkprogrammierung 5
N Socket geht auf Windows, aber auf Mac nicht ? Netzwerkprogrammierung 3
J method = PUT, aber ausgeführt wird doGet...? Netzwerkprogrammierung 4
J RMI Einfaches Hello World mit Java6 + RMI, aber ClassNotFoundException Netzwerkprogrammierung 6
A Socket Client Server Connection wird aufgebaut aber keine daten geschickt. Netzwerkprogrammierung 5
L SSL Verbindung aber Server wird erst im Programm festgelegt Netzwerkprogrammierung 4
E java.lang.NullPointerException aber nur wenns im Thread läuf Netzwerkprogrammierung 4
A [URLConnection] Bilder hochladen - aber anders! Netzwerkprogrammierung 4
H Server soll Daten schicken, aber wie? Netzwerkprogrammierung 47
M HTTP response code: 401 ; ?aber im browser ist es abrufbar? Netzwerkprogrammierung 5
K öffnen des socket schlägt fehl -> ABER: keine exception . Netzwerkprogrammierung 2
feuervogel Sockets - Lokalen Port aber nicht IP bestimmen Netzwerkprogrammierung 3
M ois nicht null, aber ois.getObject liefer exception Netzwerkprogrammierung 3
M Vom Server per Socket Empfangen, aber wieviel Bytes? Netzwerkprogrammierung 11
L JavaMail: Mail in Posteingang aber nicht in Versendet Netzwerkprogrammierung 2

Ähnliche Java Themen

Neue Themen


Oben