# Bild/Datei von einem Server an einen Client senden



## BlackWizard (6. Mai 2007)

Hallo zusammen !

Wir wollen eine Datei von einem selbstgeschriebenen Server an einen selbstgeschriebenen Client senden. Wenn das geklappt hat, soll der Client die Datei dann auch per awt anzeigen (das sollte das kleinere Problem sein).

Wir haben bis jetzt folgendes vorzuweisen:

Client:


```
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.*;

import javax.swing.BorderFactory;
import javax.swing.border.Border;

   public class gui extends Frame{
      private static final long serialVersionUID = 1L;

  
      static ServerSocket tcpSocket;
   static File saveFile;
  
     class TestActionListener implements ActionListener
     {
       public void actionPerformed(ActionEvent e)
         {
             
             
                                       try {
               Socket server = new Socket (IP_Adresse, Port);
               InputStream input = server.getInputStream();
                 OutputStream output = server.getOutputStream();
                 output.write(pixel_zahl1);
                 output.write(pixel_zahl2);
                 output.flush();
                 System.out.println(input.read());
                 server.close();
                 input.close();
                 output.close();
           } catch (UnknownHostException e1) {
               // TODO Auto-generated catch block
               e1.printStackTrace();
           } catch (IOException e1) {
               // TODO Auto-generated catch block
               e1.printStackTrace();
           }
                      try {

                byte[] fileStream = new byte[1000000];

                FileOutputStream fileOutput = new FileOutputStream("bild2.gif");

                Socket server = tcpSocket.accept();        
                InputStream in = server.getInputStream();
                byte[] buffer = new byte[1024];
                                for (int n; (n = in.read(buffer)) != -1; fileOutput.write(buffer, 0, n));
               
                                in.close();
                fileOutput.close();
                server.close();
                tcpSocket.close();

             } catch (IOException e1) {
                System.out.println("Ausgabe fehler");
                 //e.printStackTrace();
             }
                                 }
     }
               public static void main (String args[])
     {
         new gui();
              }
}
```


Server:

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

public class KleinerServer2 {
   ServerSocket server = new ServerSocket(1234);
   
   KleinerServer2() throws IOException{
      while(true){
         Socket client = server.accept();
         InputStream input = client.getInputStream();
         OutputStream output = client.getOutputStream();
         int zahl1 = input.read();
         int zahl2 = input.read();
         output.write(zahl1+zahl2);
         output.flush();
         input.close();
         output.close();
      }
   }
   public static void main(String[] argv){
      try {
         new KleinerServer2();
      }
      catch(IOException e){
         System.out.println(e);
      }
   }
}
```


Es ist klar, dass der Server nicht die gewünschte Funktion erfüllt. Unser unangepasster Client (ohne Code zum Datei-Erzeugen, nur Übergabe von int's zum Addieren) kommunizierte aber schon gut mit dem obigen Server. Die Frage ist jetzt: Wie senden wir eine lokale Datei vom Server per Netzwerk an den Client? Und wie sieht der Empfang dann korrekt auf dem Client aus? Wir haben versucht uns für beide Programme das Benötigte aus verschiedenen Threads zusammenzulesen:

http://www.java-forum.org/de/topic47154_socket-client-server-verbindung-wie-strings-senden.html
http://www.java-forum.org/de/viewtopic.php?t=33319&highlight=datei+senden
http://www.java-forum.org/de/viewtopic.php?t=48460&highlight=datei+netzwerk

Leider haben wirs nicht geschafft eine Datei zu senden. Der Client erstellt zwar eine Datei, diese ist aber immer 0 Byte groß. Intelligenterweise habe ich den Code des Servers der das Bild öffnet und als Stream an den Client senden sollte unwiderbringlich gelöscht. Das war das dumme Resultat eines Versuchs, die Art der Erzeugung des Datenstreams zu verändern (neue Datei erstellt, alte gelöscht...*selbstgeißel*). Das Bild liegt lokal im Verzeichnis des Servers und heißt z.B. "smiley.gif".

Wie dem auch sei, wir stehen auf dem Schlauch. Für jegliche Hilfe sind wir überaus dankbar .

mfg,
BlackWizard


----------



## SlaterB (6. Mai 2007)

zwei Tipps:
1.) 
Code a la

```
txt_Pixel_Zahl2 = new TextField("Zahl 2");
       txt_Pixel_Zahl2.setBounds(190, 90, 100, 20 );  // x, y, breite, höhe
       add(txt_Pixel_Zahl2);
```
ist total störend für so eine Problemstellung,
ich z.B. lese da gar nicht mehr weiter,
ich wette der Client macht nicht mehr als auch in 50 Zeilen gut reinpassen würde
(weiß ich natürlich nicht genau, da ich nicht weiter angeschaut habe  )

Konsolenprogramm!
System.out.println!

------

2.
> Leider haben wirs nicht geschafft eine Datei zu senden. Der Client erstellt zwar eine Datei, diese ist aber immer 0 Byte groß. 

was soll das für ein merkwürdiger Fehler sein?
du hast da doch zwei voneinander unabhängige Probleme:
zum einen die Bits von Server zum Client zu senden
und dann die Bits anzuzeigen oder zu speichern,

wie kann ein Speicherproblem etwas mit dem Senden vom Server zum Client zu tun haben?
es gibt nur einen sinnvollen Test: sende 'xyz'
und gib das beim Client mit 
System.out.println 
aus, funktioniert das, ja oder nein,

gleich 1 Mio. Bytes zu senden und diese ungeprüft weiterzuverarbeiten,
das kann ja nix werden.. (bzw. dann nicht wundern)

------

wieder zu Punkt 1:
falls andere auch bei dem konfusen Frage-Aufbau helfen: gut,

ansonsten ein Standard-Beispiel aus Lehrbüchern verwenden,
( http://www.galileocomputing.de/open...16_008.htm#mja069999c6fdbbfa7e611f94d70697c9f )

was funktioniert daran nicht?


----------



## thomator (7. Mai 2007)

Also nur mal so als Randbemerkung: Versucht einfach mal, das Ganze sauber zu kapseln. Das ist eines der Ziele der OOP. In einer Klasse ActionListener den Server aufzubauen ist nicht unbedingt nachvollziehbar und hat mich vom Versuch, den Quellcode mal zu lesen und nachzuvollziehen, sehr schnell abgebracht.  :wink:


----------



## BlackWizard (7. Mai 2007)

Wir haben den Code mal etwas gekürzt, hoffentlich ists jetzt übersichtlicher. Die Kapselung ist noch nicht verändert, aber man steigt wohl durch.


----------



## BlackWizard (8. Mai 2007)

Hier der geänderte Code. Wichtig dabei ist, dass wir nun eine völlig andere Implementierung haben. Das Bild wird nicht vom Server erzeugt, sondern es werden nur berechnete Koordinaten in Form eines Integer-Arrays (int[][]) an den Client übergeben. Dieser erzeugt anhand der neuen Koordinaten dann das Bild. Das Übertragen der Informationen funktioniert soweit wunderbar, nur das Bild wird nicht beim Client angezeigt.

Zur Info: Es geht erstmal darum nur ein schwarzes Rechteck zu erzeugen, eine übertragene 0 steht für schwarz, eine 1 für weiß (wid nie übertragen, ist auch irrelevant).

Hier der Server:


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

public class ServerClass {
   ServerSocket server = new ServerSocket(5678);//Lausche auf Port 5678
   
   ServerClass() throws IOException{
  
	  
      while(true){
         Socket client = server.accept();
         InputStream client_input = client.getInputStream();
         DataInputStream input = new DataInputStream(client_input);
         OutputStream client_output = client.getOutputStream();
         DataOutputStream output = new DataOutputStream(client_output);
      
         int x,y;
         int[][] bild_array;   
         
         double eckpunk_x1 = input.readDouble();
         double eckpunk_x2 = input.readDouble();
         double eckpunk_y1 = input.readDouble();
         double eckpunk_y2 = input.readDouble();
         
         int pixel_x = input.readInt();
         int pixel_y = input.readInt();
         
         int anz_Farben = input.readInt();
         
         int iteration = input.readInt();
         
         int typ = input.readInt();
         
         //Ausgabe von den ¸bergebenen Daten
         System.out.println("eckpunk_x1: " + eckpunk_x1);
         System.out.println("eckpunk_x2: " + eckpunk_x2);
         System.out.println("eckpunk_y1: " + eckpunk_y1);
         System.out.println("eckpunk_y2: " + eckpunk_y2);
         
         System.out.println("pixel_x: " + pixel_x);
         System.out.println("pixel_y: " + pixel_y);
         System.out.println("iteration: " + iteration);
         System.out.println("anz_Farben: " + anz_Farben);
         System.out.println("typ: " + typ);
         
         
         
        //Hier werden die Bilder-Koordinaten generiert und an den Client zurückgesendet
        bild_array= new int [pixel_x][pixel_y];
        for (y = 0; y < pixel_y; y++){
        	
        	for (x = 0; x < pixel_x; x++){
        		
        		bild_array[x][y] = 0;
        		System.out.print("0");
        		output.writeInt(bild_array[x][y]);
        		
        		}
        	
        System.out.println();
        	
        }
         
     
         input.close();
         
         output.flush();
         output.close();
      }
   }
   public static void main(String[] argv){
      try {
         new ServerClass();
      }
      catch(IOException e){
         System.out.println(e);
      }
   }
}
```


Und hier der Teil Code des Client-Codes, welcher eigentlich zur Bild-Erstellung gedacht war (der komplette Client, mit einigen überflüssigen Einträgen wie ihr sehen werdet, findet ihr unter http://www.firefrogz.de/index.php/Java_Temp-Paste ):


```
pixel_array = new int[pixel_x][pixel_y];
				      
				      Graphics g = null;
				      lbl_Anzeige.setBackground(Color.BLUE);
				      
				       for(int lauf_y = 0; lauf_y < pixel_y; lauf_y++){
				    	   
				    	   for(int lauf_x = 0; lauf_x < pixel_x; lauf_x++){
				    		   
				    		   pixel_array[lauf_x][lauf_y] = data_input.readInt();
				    		   System.out.print(pixel_array[lauf_x][lauf_y]);
				    		   
				    		   
				    		   if(pixel_array[lauf_x][lauf_y]==0){
				    		
				    			   g.setColor(Color.BLACK); 
				    		       g.fillRect( lauf_x + 811, lauf_y + 51, 1, 1 );
				    		       lbl_Anzeige.paint(g);
				    		         
				    		   }
				    		   /*
				    		  else if(pixel_array[lauf_x][lauf_y]==1){
				    			   g.setColor(Color.WHITE); 
				    		       g.fillRect( lauf_y + 50, lauf_x + 810, 1, 1 );
				    		   }
				    		   */
				    		   
				    	   }
				    	   System.out.println();
				    	   
				       }
```

Ohne die ganzen Graphics-Einträge printet der ohne Probleme die vom Server übertragenen Zahlen aus. Übrigens, wie stelle ich es an, dass ich bspw. den Server über eine Konsole starte? Bis jetzt haben wir immer zwei verschiedene Rechner und Eclipse dafür benutzt, das ganze über localhost laufen zu lassen würde uns erlauben auch alleine nach Fehlern zu suchen. Client unter Eclipse, Server in der normalen Konsole.

mfg und DANKE nochmal,
BlackWizard


----------



## SlaterB (8. Mai 2007)

> Übrigens, wie stelle ich es an, dass ich bspw. den Server über eine Konsole starte?

java Programmname

?

----------

verstehe ich jetzt richtig, dass es nun keine Probleme in der Übertragung mehr gibt,
sondern nur die Zeichnung einer Grafik nicht funktioniert?

passend in diesem Thread 

man zeichnet in einer GUI mit paintComponent, was ist davon vorhanden?
eine TestGUI gerne mit Thread oder so ist immer noch maximal 100 Zeilen lang,
Server/ Client-Code ist da aber völlig fehl am Platze, was hat die Quelle der Daten mit dem Zeichnen zu tun?

bitte lauffähiges kurzes Programm posten indem der Fehler auftritt,
und was ist der Fehler? kein Bild/ Exception/ ..?


----------



## skullbocks (10. Mai 2007)

Hi,

das hier beschreibene Problem hat sich erledigt, wir haben ein neues Problem aufgetan und einen neuen Thred gestartet.

Vielen Dank für eure Hilfe

mfg 

skullbocks & BlackWizard


----------

