# Server/Client Verbindung - Datei schreiben



## rapthor (6. Jul 2004)

Hallo,

ich weiß dass hier überall Schnipsel hilfreicher Informationen herumliegen, aber diese alle zu MEINER Lösung zusammenzusuchen würde viel Zeit beanspruchen und daher wollte ich hier einmal meinen Quelltext für einen Clienten als auch einen Server darstellen und die Frage stellen, wie ich in der Server Applikation die Datei

"test.tst"

die ja vom Clienten kommen soll auf die Festplatte schreiben lassen kann? Wohin genau auf der Festplatte, ist erstmal egal. Mir geht es rein um's Prinzip. Welchen Input / OutputStream muss ich verwenden ... ich habe leider nicht so viel Ahnung von Streams und habe das meiste selber nur so zusammengesucht.


```
import java.io.*;
import java.net.*;

class DateiTransferClient {

    ObjectOutputStream ausgang;
	ObjectInputStream eingang;

	public void runClient() {

		Socket clientSocket;

		try {
			System.out.println("Versuche Verbindung aufzubauen ...");

			// Wo ist der Server ?
			clientSocket = new Socket(
            	InetAddress.getByName("127.0.0.1"), 2000);

         	ausgang = new ObjectOutputStream(
                      clientSocket.getOutputStream() );
        	ausgang.flush();

        	eingang = new ObjectInputStream(
            		  clientSocket.getInputStream() );
		}
		catch (ConnectException ce) {
			System.out.println("Verbindung fehlgeschlagen ! Firewall ? Server nicht aktiv ?\n");
			//ce.printStackTrace();
		}
		catch (EOFException eof) {
			System.out.println("EOF Fehler !\n");
		}
		catch (IOException io) {
			System.out.println("I/O Fehler !\n");
			//io.printStackTrace();
		}

		try {
			this.sendData( new File("c:test.tst") );
		}
		catch (NullPointerException np) {
			System.out.println("NullPointer irgendwas .... wegen der Datei\n");
		}

	}



   private void sendData( File datei )
   {
      try {
         // Füllen des Buffers
         ausgang.writeObject(datei);

         // Losschicken der Daten im Buffer
         ausgang.flush();
         System.out.println( "\nDatei geschickt !");
      }
      catch ( IOException cnfex ) {
         System.out.println(
            "\nFehler beim Senden der Datei !" );
      }
   }



   public static void main(String[] args) {

      DateiTransferClient app = new DateiTransferClient();
      app.runClient();
   }

}
```

^---- Das ist der Client





```
import java.io.*;
import java.net.*;

class DateiTransferServer {

    ObjectOutputStream ausgang;
	ObjectInputStream eingang;

	public void runServer() {

     	ServerSocket serverSocket;
        Socket verbindungsSocket;

      try {

         serverSocket = new ServerSocket( 2000 , 100 );

         while ( true ) {

            System.out.println( "Warte auf Verbindung ..." );
            verbindungsSocket = serverSocket.accept();

            System.out.println( "Verbindung mit " +
               verbindungsSocket.getInetAddress().getHostName() );

            ausgang = new ObjectOutputStream(
                        verbindungsSocket.getOutputStream() );
            ausgang.flush();

            eingang = new ObjectInputStream(
                        verbindungsSocket.getInputStream() );

            System.out.println( "Empfange Daten ...." );

/*
            do {


               try {

                  // Hier soll die Datei geschrieben werden,
                  // die vom Client empfangen wird (test.tst) !!

               }
               catch ( ClassNotFoundException cnfex ) {
                  System.out.println("Unbekannter Objekttyp !");
               }

            } while (  /* !Abbruchbedingung */ );

*/


            // Verbindung beenden
            System.out.println( "Verbindung wird unterbrochen ..." );
            ausgang.close();
            eingang.close();
            verbindungsSocket.close();
            System.out.println( "BEENDET !" );
         }
      }
      catch ( EOFException eof ) {
         System.out.println( "Client hat die Verbindung unterbrochen !" );
      }
      catch ( IOException io ) {
         System.out.println( "IO Fehler !" );
         io.printStackTrace();
      }
	}


   public static void main(String[] args) {

      DateiTransferServer app = new DateiTransferServer();
      app.runServer();
   }

}
```

^--- Und das ist mein Server !

Ich hoffe man kann mir hier ein wenig helfen .... wäre dafür wirklich sehr dankbar.

Rapthor


----------



## Dante (6. Jul 2004)

Hm, warum nicht einfach den InputStream des Sockets in nen FileOutputStream schreiben?


----------



## Guest (6. Jul 2004)

An welcher Stelle meinst du jetzt? Und was genau muss ich dafür umschreiben .....


----------



## rapthor (6. Jul 2004)

<Beitrag nochmal selbst rausgelöscht>


----------



## rapthor (6. Jul 2004)

Meine Server Applikation sieht jetzt folgendermaßen aus ......



```
import java.io.*;
import java.net.*;

class DateiTransferServer {

	ObjectInputStream eingang;

	public void runServer() {

     	    File datei = new File("c:\\test.jap");

     	    ServerSocket serverSocket;
                    Socket verbindungsSocket;

                      try {

                         serverSocket = new ServerSocket( 2000 , 100 );

                         while ( true ) {

                            System.out.println( "Warte auf Verbindung ..." );
                            verbindungsSocket = serverSocket.accept();

                            System.out.println( "Verbindung mit " +
                                     verbindungsSocket.getInetAddress().getHostName() );

                            eingang = new ObjectInputStream(
                                     verbindungsSocket.getInputStream() );

                            System.out.println( "Empfange Daten ...." );

                            try{
                                           // Was muss ich hier machen, damit die Datei,
                                           // die über "eingang" kommt, ordnungsgemäß
                                           // gespeichert wird undzwar als "c:\test.jap" ?

	                    }
	                    catch(Exception e){}



            // Verbindung beenden
            System.out.println( "Verbindung wird unterbrochen ..." );

            verbindungsSocket.close();
            ausgang.close();

            System.out.println( "BEENDET !" );
         }
      }
      catch ( EOFException eof ) {
         System.out.println( "Client hat die Verbindung unterbrochen !" );
      }
      catch ( IOException io ) {
         System.out.println( "IO Fehler !" );
         io.printStackTrace();
      }
	}


   public static void main(String[] args) {

      DateiTransferServer app = new DateiTransferServer();
      app.runServer();
   }

}
```

Wie schaff ich es jetzt, dass mir die Daten, die über den ObjectInputStream kommen als C:\test.jap Datei abgespeichert werden?
Ich habe sichergestellt, dass über den ObjectInputStream wirklich eine Datei geschickt wird.


----------



## meez (6. Jul 2004)

Ueber ObjectInputStream/ObjectOuputStream kann man keine "Dateien" senden, sondern nur Objekte...
Das File Object, welches du senden willst, entält nur Metadaten über die Datei, aber nicht deren Inhalt.

Wenn du die Datei schreiben willst, geht das so:



Beim Client die Daten Senden:


```
OuputStream out = clientSocket.getOutputStream();
InputStrem in = new FileInputStream("c:\\test.tst");
byte[] buffer = new byte[1024];
int n;

while ((n = in.read(buffer)) != -1)
   out.write(buffer, 0, n);
```


Beim Server die Daten Empfangen, und auf die Platte schreiben:


```
InputStream in = verbindungsSocket.getInputStream();
OuputStream out = new FileOuputStream("c:\\test.jap");

byte[] buffer = new byte[1024];
int n;

while ((n = in.read(buffer)) != -1)
   out.write(buffer, 0, n);
```


----------



## rapthor (7. Jul 2004)

Ui,

also im Grunde genommen funktioniert das jetzt bei mir auch ... dank deiner Hilfe. Allerdings ist die empfangene Datei immer 2 Byte größer, als die, die ich losgeschickt habe.
Undzwar entstehen diese zusätzlichen Informationen am ANFANG der neuen Datei ... danach ist alles wie im Original.


----------



## rapthor (7. Jul 2004)

Hat geklappt .. hab irgendwo was doppelt zugewiesen ... jetzt stimmen die Dateigrößen wieder


----------



## rapthor (7. Jul 2004)

Warum spuckt mir die Server Applikation denn plötzlich diesen fehler aus, wenn sie ganz normal den Port 10000 benutzen soll ?


```
java.net.SocketException: Connection reset
        at java.net.SocketInputStream.read(SocketInputStream.java:168)
        at java.net.SocketInputStream.read(SocketInputStream.java:182)
        at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java
:2133)
        at java.io.ObjectInputStream$BlockDataInputStream.readBlockHeader(Object
InputStream.java:2313)
        at java.io.ObjectInputStream$BlockDataInputStream.refill(ObjectInputStre
am.java:2380)
        at java.io.ObjectInputStream$BlockDataInputStream.read(ObjectInputStream
.java:2539)
        at java.io.ObjectInputStream.read(ObjectInputStream.java:794)
        at java.io.InputStream.read(InputStream.java:89)
        at DateiTransferServer.runServer(DateiTransferServer.java:48)
        at DateiTransferServer.main(DateiTransferServer.java:82)
```

Mein Server erstellt zwar die Datei, aber sie ist danach leer!
Grade eben ging's noch ... arg was hab ich jetzt gemacht? Hat einer ne Ahnung?


----------



## meez (7. Jul 2004)

Du hast schon wieder einen ObjectInputStream drin...


----------



## rapthor (7. Jul 2004)

Geht wieder alles ...
hab das Programm jetzt mit nem Rechner hinter einer Firewall getestet ... ich selber sitze auch hinter einer Firewall. Allerdings müssten Port 80 und 21 funktionieren. Wenn ich aber meine Programme jetzt auf diesem Port laufen lasse, kriegt er dennoch keine Verbindung aufgebaut.


----------



## meez (7. Jul 2004)

rapthor hat gesagt.:
			
		

> Geht wieder alles ...
> hab das Programm jetzt mit nem Rechner hinter einer Firewall getestet ... ich selber sitze auch hinter einer Firewall. Allerdings müssten Port 80 und 21 funktionieren. Wenn ich aber meine Programme jetzt auf diesem Port laufen lasse, kriegt er dennoch keine Verbindung aufgebaut.



Wenns eine Packetfilter FW ist, dann wird sie merken, dass du ein unerlaubtes Protokoll benutzt...Oder du benutzt schon von Anfang an eine unerlaubte IP...


----------



## rapthor (7. Jul 2004)

Bei mir ist es der Router mit integrierter Firewall ... nen Vigor 2300. Gibt es keine Möglichkeit dem irgendwie vorzugaukeln dass mein JAVA Programm nen "liebes" ist und über Port 80 oder 21 gehen darf?


----------



## rapthor (19. Jul 2004)

Kann man dem Server nicht auftragen, die Daten über den 80er Port nach außen zu tunneln? Sagen wir mal über das HTTP Protokoll.


----------



## meez (20. Jul 2004)

Kannst du schon...Musst das Prog dann halt unter root laufen lassen...


----------



## rapthor (29. Jul 2004)

Das Programm führe ich als Administrator meines Windows XP Systems aus. Entspricht also dem ROOT eines LINUX Systems, wenn ich mich nicht täusche. Aber was hat dass Ausführen als Admin damit zu tun, ob die Firewall mich durchlässt oder nicht? Die Firewall interessiert es doch nicht ob ich im eigenen System der Admin bin.


----------

