# Probleme beim weiter senden von Datein



## Planetasia (29. Jun 2009)

Hallo,

ich versuche gerade "einfach" ein txt-File von einem Client zu einem anderen Client zu senden. Das senden vom Client zum Server funktioniert soweit, aber sobald ich die datei weiter senden will, wird die connection jedes mal getrennt! Kann mir jemand sagen was da falsch ist?

Server:

```
// Nachricht empfangen und....
byte data[] = new byte[1024];

InputStream is = clientSocket.getInputStream();
FileOutputStream file = new FileOutputStream("C:\\testJava.txt");

// Datei zwischen speichern! 
int size;

while ((size = is.read(data)) != -1)
{
    file.write(data, 0, size);
    file.flush();
}

					
file.close(); 

// Datei weiter an den anderen Client senden:
int size; 
		File openfile= new File("C:\\testJava.txt");
		 try {
		OutputStream os= clientSocket.getOutputStream();
		FileInputStream file= new FileInputStream(openfile);
		  				
			byte data[] = new byte[1024];
			
			this.out.println("File");
			
			while((size=file.read(data))!= -1){
				os.write(data, 0, size);
				os.flush();
			}
		
			os.close();
			file.close();
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
```

Client senden: (File wird über FileChooser ausgewählt!)

```
public void WriteMesssage(File f){
		
		out.println("File");
		out.flush();
		
		 File myFile = f;
		 int size;
		 byte data[]= new byte[1024];
	    try {
			OutputStream os= mClient.getOutputStream();
			
			FileInputStream file= new FileInputStream(myFile);
			
			while((size=file.read(data))!=-1){
				os.write(data, 0, size);
				os.flush();
			}
			os.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
```

Client empfangen des Files --> gleich wie beim Server!


lg


----------



## Paddelpirat (29. Jun 2009)

Hi,

habe zwar gerade keine Zeit deinen Code auszuprobieren, aber spontan würde ich sagen, dass der Schreibvorgang fehl schlägt, da du den InputStream nicht mit is.close() beendet hast und somit der Socket blockiert wird.


----------



## Planetasia (29. Jun 2009)

hm...

danke erstmal für deine Antwort. Leider hat das auch nicht geholfen.

Meine Fehlermeldung am Server: 

Exception in thread "Thread-0" java.lang.NullPointerException
	at Server.run(Server.java:91)
Zeile 91:


```
while!(line = in.readLine()).equalsIgnoreCase("/quit"){
// hier steht der Code zum Nachrichten bzw. Datein zum empfangen!!
```

und die Fehlermeldung am Client:

java.net.SocketException: socket closed
	at java.net.SocketInputStream.socketRead0(Native Method)
	at java.net.SocketInputStream.read(Unknown Source)
	at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
	at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
	at sun.nio.cs.StreamDecoder.read(Unknown Source)
	at java.io.InputStreamReader.read(Unknown Source)
	at java.io.BufferedReader.fill(Unknown Source)
	at java.io.BufferedReader.readLine(Unknown Source)
	at java.io.BufferedReader.readLine(Unknown Source)
	at Client.run(Client.java:138)


```
while(!(line = in.readLine()).equals("/quit")){
    //selbe wie beim Server
   }
```

lg


----------



## Paddelpirat (29. Jun 2009)

Der Ausdruck line = in.readLine() wird null, falls du alle Daten vom Socket eingelesen hast. Änder die Abfrage mal in folgende Bedingungen ab:


```
while((line = in.readline()) != null && !line.equalsIgnoreCase("/quit")) {
```

Wenn line null sein sollte, also er nichts mehr zum einlesen hat wird die Schleife abgebrochen, ansonsten überprüft er noch, ob die eingelesene Zeile ungleich "/quit" ist.


----------



## Planetasia (29. Jun 2009)

hm...wenn ich auf != null abfrage, dann werde ich ja gleich disconnected.... weil ich schicke doch nicht
immer Nachrichten bzw. files! Oder hab ich das falsch verstanden!?

Wie kann ich das machen, dass mein Server auf Nachrichten und auf Files wartet!?
Auf Nachrichten warten und diese dann an die Clients weiter schicken funktioniert.
--> sobald ich auf !=null abprüfe, dann funktioniert gar nix mehr :-( 
Der Client kann sich nicht mal auf dem Server anmelden!

lg


----------



## Paddelpirat (29. Jun 2009)

Dann am besten:


```
boolean isAlive=true;

while(isAlive) {
  line = in.readLine();
  if(line != null) {
    if(line.equalsIgnoreCase("\quit")) isAlive = false;
    else {
         //hier kommt dein übriger Code rein
    }
  }
}
```


----------



## Planetasia (29. Jun 2009)

hätte ich so auch schon versucht.
Allerdings wird auch dabei die Verbindung sofort getrennt...
ich schick dir mal den ganzen code.... vielleicht erwähne ich irgendetwas wichtiges nicht.....


```
import java.awt.Color;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;

import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;




public class Client extends Thread {
	private static HashMap<String, Client> clients = new HashMap<String, Client>();
	private Socket clientSocket;
	private BufferedReader in;
	private PrintWriter out;
	private String name;
	private ClientStatus status;
	MutableAttributeSet mAttributes;
	private boolean changeAttributes;
	
	//Zum Daten senden!!!
	private boolean mFile;
	private InputStream mGetFile;
	private ObjectInputStream mInStream;
	private ObjectOutputStream mOutStream;
	
	
	public Client(Socket s) {
		clientSocket = s;
		status = ClientStatus.CONNECTED;
		try {
			in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
			out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
			mOutStream=  new ObjectOutputStream(clientSocket.getOutputStream());
			mInStream = new ObjectInputStream(clientSocket.getInputStream());
			mAttributes=null;
			mAttributes= new SimpleAttributeSet();
			mFile=false;
		} catch (IOException e) {
			e.printStackTrace();
		}	
	}
	public String getAddress() {
		return clientSocket.getInetAddress().getHostAddress();
	}
	public ClientStatus getStatus() {
		return this.status;
	}
	public void setStatus(ClientStatus s) {
		this.status = s;
	}
	
	public void setAttributes(MutableAttributeSet _attributes)
	{
		
			mAttributes= _attributes;
		
		
	}
	public MutableAttributeSet getAttributes()
	{
		return mAttributes;
	}
	
	@Override
	public void run() {
		try {
			String line;
			boolean sent=false;
			int x=0;
			while(!(line = in.readLine()).equalsIgnoreCase("/quit")) {
				sent=false; // After whispering....to send message to everybody again....

								
			//DATEN EMPFANGEN/SENDEN.......................
			
				if(line.equals("File")){	
					
					 
			        byte data[] = new byte[600000];

			        InputStream is = clientSocket.getInputStream();
			        FileOutputStream fileOut = new FileOutputStream("C:\\testJava.txt");

			        // Datei zwischen speichern! 
			        int size;
			        while ((size = is.read(data)) != -1)
			        {
			            fileOut.write(data, 0, size);
			            fileOut.flush();
			        }
			       
			        					
					fileOut.close();
					is.close();
					
									
					  System.out.println("Empfangen");
				   // sendFile();
				    out.println("ready");
				    mFile=true;
				    
				}
				
				/**
				 * Datei weiter schicken:
				 */
				if(line.equals("send")){
					System.out.println("los gehts....");
					sendFile();
					x=2;
				}
				
		

				if (this.status == ClientStatus.NAMED && !mFile) {
					
					if(line.equals("/show"))
					{
						int i=0;
						
						for(Client c: clients.values()){
							this.out.println(i+ ". Client = " + c.name);
							
							c.out.flush();
							sent=true;
							i++;
							
						}
					}
					if (line.charAt(0)=='/' && sent==false) {
						if (line.indexOf("/help")!=-1) {
							
						} 
						else {
							//whisper to a client
							int i=0;
							GregorianCalendar calender= new GregorianCalendar();
							DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM);
							df= DateFormat.getTimeInstance(DateFormat.SHORT);
							
							List<Character> charlist = new ArrayList<Character>(); // List for reading the name
							
													
							//holt sich alle chars vom namen (ohne "/")
							while(line.charAt(i)!=' '){ 
								
								if(line.charAt(i)!= '/'){
									charlist.add(line.charAt(i));	
								}
								
								i++;
							}
						
							int size=charlist.size(); // gets the size of the array for allocate the memory for the array
							
							
							char [] arr= new char[size]; // gets the name
							
							for(int j=0; j<size; j++)
							{
								arr[j]=charlist.get(j); //gets the single char of the List (name)
							}
							String _name= new String(arr); // new String with the name
							
							
							charlist.clear(); // delete the list
							
							int lenght= line.length()-size-2;
							char [] send_txt= new char[lenght];
							int cnt=0;
							//saves every char of the message
							for( i=size+2; i< line.length(); i++)
							{
							send_txt[cnt]=line.charAt(i);
								cnt++;
							}
						
							String help_txt= new String(send_txt); //save the list to an String
						
							 //is looking for the client to sent the message
							int xyz=0;
							for (Client c: clients.values())
							{
								
								if(c.name.compareTo(_name)==0)
								{
									c.out.println("[ "+df.format(calender.getTime())+"] "+ this.name+"(flüstert)> "+help_txt);
									c.out.flush();
									sent=true;
									xyz++;
								
								}
								
							}
							
							if(xyz==0){
								this.out.println(_name+ " befindet sich nicht im Chat");
							}
							
						
						}
					} 

					else {
						if(sent==false){
						// Send message to all NAMED users
						GregorianCalendar calender= new GregorianCalendar();
						DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM);
						df= DateFormat.getTimeInstance(DateFormat.SHORT);
						
						for (Client c : clients.values()) {
							if (!c.equals(this)) {
								c.out.println("[ "+df.format(calender.getTime())+"] "+ this.name+"> "+line);
								c.out.flush();
								
								System.out.println("Nachricht an: "+c.name+" lautet:" +line);
							}
						}
					}
				} 
					this.out.flush();
			}
				
				if(x==2){
					System.out.println("Ende....");
					mFile=false;
					this.out.println("ENDE");
				}
				
				else if(this.status == ClientStatus.CONNECTED) {
					if (line.indexOf("/name")!=-1) {
						if (line.length()<128) { 
							name = line.substring(6);
							clients.put(name, this);
							this.setStatus(ClientStatus.NAMED);
							System.out.println("Client provided name: "+name);
							System.out.println(clients.size()+ "named Clients connected");
						} else {
					System.out.println("Nickname too long, please provide a shorter name!");
						}
					} 
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		finally {
			try {
				System.out.println("Client "+name+" disconnected");
				in.close();
				out.close();
				clientSocket.close();
				clients.remove(this);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}
	
	public void sendFile(){
		int size; 
		File openfile= new File("C:\\testJava.txt");
		out.println("File");
		try {
		OutputStream os= clientSocket.getOutputStream();
		FileInputStream file= new FileInputStream(openfile);
		  				
			byte data[] = new byte[600000];
			
			this.out.println("File");
			
			while((size=file.read(data))!= -1){
				os.write(data, 0, size);
				os.flush();
			}
		
			os.close();
			file.close();
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
}
```

vielen dank für deine bemühungen!!

lg


----------



## Paddelpirat (29. Jun 2009)

Hmm in Zeile 101 steht bei dir:


```
InputStream is = clientSocket.getInputStream();
```

das brauchst du nicht, da du den InputStream ja schon in dem Konstruktor definiert hast.

Außerdem ist das is.close() ein Problem... wenn du das in der while-Schleife aufrufst, ist es kein Wunder, dass in eine NullPointerException auftaucht, weil du in der while-Schleifen-Bedingung ja wieder auf deinen InputStream zugreifst... sorry das war in deinem ersten Post nicht so ersichtlich, deswegen hatte ich das als Lösung vorgeschlagen *wink*.

Am besten änder die Stellen nochmal ab und schreib, wodran er sich als nächstes aufhängt...


----------



## Planetasia (29. Jun 2009)

hab mich grad noch etwas damit herum gespielt.... sobald die datei angekommen ist empfängt der Server gar nix mehr (ab zeile 125).... nicht mal normale nachrichten..... der String "line" ist immer null!
hm...hat irgendjemand eine idee warum!??? bevor ich eine Datei sende kommt es auch nicht zu diesem Problem...


lg

edit:
@Paddelpirat
auch nachdem ich das "is" nich close!!

es kommt trotzdem ein null zurück!!


----------



## Paddelpirat (29. Jun 2009)

Ich hab mal eine kleine Logik-Frage zu deinem Programm, da ich ja jetzt nur den Client sehe. Normalerweise läuft das ja so ab, dass man den Server startet und dieser wartet auf einen Request von einem Client.

Nun startet man einen (oder mehrere) Client(s). Dieser öffnet nun eine Verbindung zu dem Server (das hast du wohl in irgendeiner anderen Klasse, tut hier aber auch nichts zur Sache). Aber nun müsste der Client einen Request an den Server schicken a la: "get file: filename", oder sowas in der Art.
Der Server empfängt dieses Request und Antwortet darauf: "hier hast du es: <datadatadata....>".

Nun ist das aber so, dass dein Client wohl nur gestartet wird und dann wartet, bis er eine Nachhricht vom Server bekommt. Aber woher weiß der Server, dass der Client was haben möchte?


----------



## Planetasia (29. Jun 2009)

Sorry.....das hab ich nicht ganz klar gemacht.....
Den Client den du da siehst ist nicht der eigentliche Client.... sondern das ist ein Serverseitiger Client, der die Nachrichten aller Clients empfängt.... dieser Client schickt die empfangenen Nachrichten an alle weitern Clients weiter...
Es ist so.... ich habe einen Client (Clientseitig) der über einen Filechooser ein File auswählen kann. Zu beginn wähle ich nur mal ein txt-File aus.... dann sendet der Client dem Server einen Text...."File", damit der Server weiß dass es sich um ein File handelt. Danach wird das File an den Server gesendet! 

Nun will ich dass der Server das empfangen File, vom Client, an den Client wieder zurück sendet (um zu testen ob es funktioniert) später soll der Server das File natürlich an einen anderen Client weiter schicken!...

Das vom Server empfangene File finde ich auch auf meiner Festplatte.... also weiß ich das der Server das File zumindest empfängt. Der nächste Schritt wäre nun dass der Server das File wieder öffnet und dieses an den Client zurück sendet! Allerdings ist nun das problem dass irgendwie die ganze Verbindung dabei verlorern geht! Und ich keine Ahnung hab warun :-(

Um einfach zu testen hätte ich jetzt auch versucht direkt nach dem Speichern des Files (vom Server) eine Nachricht an den Client wieder zu senden.... allerdings wird nicht mal mehr diese Nachricht gesendet!


Bin schon am  verzweifeln :-(

lg


----------

