# Chat Server/mehre Client



## dng (6. Jul 2014)

Hallo Zusammen,

ich habe hier ein problem mit der Compilierung.Und ich weisst nicht woran liegt die Fehler.
Kann jemand in mein Kode schauen. voran liegt die Fehler.Danke

hier ist der Server-Code


```
package tools;

import java.io.*;
import java.net.*;
import java.util.*;
/**
 * @author dng
 *
 */
public class Server implements Runnable {
	ServerSocket server;
	int port;
	private BufferedReader socket_in;
	private PrintWriter socket_out;
	private Socket clientSocket;
	public  List<ConnectionHandler> cHandler =new ArrayList<>();
	
	
	public Server(int port){
		this.port=port;
	}
	//Verbindung Server-Client
	@Override
	public void run() {
	//public void verbindungClientServer(){
		// TODO Auto-generated method stub
		try {
			server= new  ServerSocket(port);
			
			
			System.out.println("waiting for connection request from client");
			while(true){
				try {
				 clientSocket =  server.accept();
				 ConnectionHandler handler = new ConnectionHandler(clientSocket);
				 cHandler.add(handler);
				 new Thread(handler).start();
				 
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

				 System.out.println(clientSocket.getInetAddress()+" is connected");
				 String message="welcome to Server";
				 String msg=message.toString() + '\n';
				 socket_out.println(msg);
			     socket_out.flush();
				 //clientSocket.close();
				/* socket_out.print(socket_in.readLine());
				 socket_out.flush();*/
				 
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	public static void main(String []args){
		
		new Thread(new Server(9075)).start();
		
	// TODO Auto-generated method stub
	}


	
}
```

und hier ConnectionHandler

```
/**
 * 
 */
package tools;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.*;

/**
 * @author dng
 *
 */
public class ConnectionHandler implements Runnable{
	Socket conHandsocket;
	volatile boolean interrupted;

	ConnectionHandler(Socket conHandsocket) {
		this.conHandsocket = conHandsocket;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		//Ein Handler der Verbindung aller Clients Verbindung
		try {
			System.out.println("waiting for connection request from client");
			//conHandsocket.setSoTimeout(100);
			BufferedReader socket_in = new BufferedReader(new InputStreamReader(conHandsocket
				.getInputStream()));
			PrintWriter socket_out = new PrintWriter(conHandsocket.getOutputStream(), true);
		
			
			//conHandsocket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

}
```

und hier der Client


```
package tools;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

/** @author Eugen Labun */
public class Client {
	Socket clientsocket;
	int port;
	private BufferedReader socket_in;
	private PrintWriter socket_out;
	private String name;
	private String host;

	public Client( String host, int port) {
		this.port = port;
		this.host = host;
	}

	public void verbindungAufbau() {
		try {
			clientsocket = new Socket(host, port);
			verbindungAufbau();
			socket_in = new BufferedReader(new InputStreamReader(clientsocket.getInputStream()));
			socket_out = new PrintWriter(clientsocket.getOutputStream(),true);
			String message=(String)socket_in.readLine();
			System.out.println(" Message from server: "+message);
			//clientsocket.close();
			//socket_out.flush();
		} catch (IOException ex) {
			/*}finally{
		
				try {
					clientsocket.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}*/
			}
			
		}

		
	

	public static void main(String[] args) {
		//new Thread(new Client("localhost", 9075)).start();
		new Client("localhost",9075).verbindungAufbau();
	}
/*
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try{
			verbindungAufbau();
			socket_in = new BufferedReader(new InputStreamReader(clientsocket.getInputStream()));
			socket_out = new PrintWriter(clientsocket.getOutputStream(),true);
			String message=(String)socket_in.readLine();
			System.out.println(" Message from server: "+message);
			clientsocket.close();
			socket_out.flush();
			
		}catch(Exception e){
		
		}finally{
		
				
		
			
		}
		
	}*/
}
```




Danke

MFG dng


----------



## MR_UNIX (7. Jul 2014)

Du könntest ja wenigstens mal den Fehler mit posten.


----------



## Phash (7. Jul 2014)

könnte mir jetzt erstmal vorstellen, dass du in deiner "while(true)" Schleife dauernd neue Threads startest, und zwar ohne Bedingung...

Du solltest evtl nur einen Thread starten, wenn sich ein Client verbindet, und nicht dauernd... (du wirst wohl einige Male pro Sekunde was neues starten und das knallt halt dann recht zügig)


Allerdings ist es schwer, wenn du keine Fehlermeldung postest.

P.S. mach mal einen Breakpoint in deinen Server, und debug das Ganze


----------



## turtle (7. Jul 2014)

Dein Connection-Handling ist falsch.

Beispielsweise hast du im Server-Code folgende Zeilen

```
socket_out.println(msg);
```
socket_out muss aber an der Stelle null sein, also NPE. Du behandelst ja jeden Client in einem eigenen Thread. Daher muss der Server "nur" auf neue Clients warten (accept).

```
System.out.println("waiting for connection request from client");
		    clientSocket = server.accept();
		    ConnectionHandler handler = new ConnectionHandler(clientSocket);
		    cHandler.add(handler);
		    new Thread(handler).start();
		}
```
Im Client sehe ich einen rekursiven Aufruf, der ebenfalls keinen Sinn macht.

```
public void verbindungAufbau() {
        try {
            clientsocket = new Socket(host, port);
            verbindungAufbau();
```
Das habe ich mal weggemacht und schon läuft es. Jedenfalls kann ein Client sich verbinden, Eingaben machen und diese werden an den Server geschickt.


Spoiler: Server





```
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

/**
 * @author dng
 * 
 */
public class Server implements Runnable {
    ServerSocket server;
    int port;
    private BufferedReader socket_in;
    private PrintWriter socket_out;
    private Socket clientSocket;
    public List<ConnectionHandler> cHandler = new ArrayList<>();

    public Server(int port) {
	this.port = port;
    }

    // Verbindung Server-Client
    @Override
    public void run() {
	try {
	    server = new ServerSocket(port);

	    try {
		while (true) {
		    System.out.println("waiting for connection request from client");
		    clientSocket = server.accept();
		    ConnectionHandler handler = new ConnectionHandler(clientSocket);
		    cHandler.add(handler);
		    new Thread(handler).start();
		}
	    } catch (IOException e) {
		e.printStackTrace();
	    }
	} catch (IOException e) {
	    e.printStackTrace();
	}

    }

    public static void main(String[] args) {

	new Server(9075).run();
    }
```
}





Spoiler: Client





```
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

/** @author Eugen Labun */
public class Client {
    Socket clientsocket;
    int port;
    private BufferedReader socket_in;
    private PrintWriter socket_out;
    private String name;
    private String host;

    public Client(String host, int port) {
	this.port = port;
	this.host = host;
    }

    public void verbindungAufbau() {
	try {
	    clientsocket = new Socket(host, port);
	    socket_in = new BufferedReader(new InputStreamReader(clientsocket.getInputStream()));
	    socket_out = new PrintWriter(clientsocket.getOutputStream(), true);
	    String message = (String) socket_in.readLine();
	    System.out.println(message);
	    while (true) {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String clientLine = br.readLine();
		socket_out.println(clientLine);
	    }
	} catch (IOException ex) {
	    ex.printStackTrace();
	}

    }

    public static void main(String[] args) {
	new Client("localhost", 9075).verbindungAufbau();
    }
```
}





Spoiler: ConnectionHandler 





```
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.*;

/**
 * @author dng
 * 
 */
public class ConnectionHandler implements Runnable {
    Socket conHandsocket;
    volatile boolean interrupted;
    private BufferedReader socket_in;
    private PrintWriter socket_out;

    ConnectionHandler(Socket conHandsocket) {
	System.out.println(conHandsocket.getInetAddress() + " is connected");
	this.conHandsocket = conHandsocket;
	try {
	    socket_in = new BufferedReader(new InputStreamReader(conHandsocket.getInputStream()));
	    socket_out = new PrintWriter(conHandsocket.getOutputStream(), true);
	} catch (IOException e) {
	    e.printStackTrace();
	}
    }

    @Override
    public void run() {
	String message = "Welcome to Server";
	String msg = message.toString() + '\n';
	socket_out.println(msg);
	socket_out.flush();
	System.out.println("waiting for connection request from client");
	while (true) {
	    try {
		String readLine = socket_in.readLine();
		System.out.println("Client sent:" + readLine);

		// conHandsocket.close();
	    } catch (IOException e) {
		e.printStackTrace();
	    }
	}

    }
```
}


----------



## Anti-Banane (7. Jul 2014)

leute ... dafür braucht man doch keine fehlermeldungen .. den code kann man doch mal eben schnell im kopf durchgehen

server :

main ->
Thread.start() ->
new ServerSocket() ->
accept() ... und genau so macht man es mit normalen I/O > in einem loop auf eingehende verbindungen warten, also völlig ok ... ->
new ConnectionHandler() ->
List.add() ->
Thread.start() ->
String gedöns ... ernsthaft ? String.toString() ... OUCH ! ... ->
socket_out.println() > NPE ->
flush() > NPE

client :

main ->
verbindungAufbau() ->
new Socket() ->
verbindungAufbau() > rekursiver aufruf > StackOverflow


ernsthaft ... ihr wollte fehlermeldungen obwohl man schon beim bloßen querlesen erkennt was hier sache ist ... nämlich das TO mal überhaupt keine ahnung von dem hat was er eigentlich machen will und daher nur code ausm netz zusammen geklickt hat


----------



## dng (7. Jul 2014)

Hallo,

Danke fuer die Anrworten,die Fehlermeldung war 

*Exception in thread "Thread-0" java.lang.NullPointerException
    at tools.Server.run(Server.java:47)
    at java.lang.Thread.run(Thread.java:744)
*


ich schau mal was @turtel gepostet hast.Ich bin noch beim lesen


----------



## dng (7. Jul 2014)

Hallo zusammen, 
es gibt par sachen, dass ich nicht versteht   bei  @turtel, koenntest du mir ,bitte es erklaere  @turtel oder andere koennen auch dazu sagen

```
while (true) 
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String clientLine = br.readLine();
        
        socket_out.println(clientLine);
```




danke 
mfg sng


----------



## turtle (7. Jul 2014)

Nun, dein Client-Code lief so, dass er etwas ausgab und dann war das mit dem Client.

Da dein Code zum Beenden eines Client noch nicht fertig ist und der Server "ungehalten" reagiert, wenn der Client einfach wegkracht, habe ich das Verhalten geändert.

Und zwar läuft "mein" Client in einer Endlosschleife und liest darin Zeilen ein, die der Benutzer eingibt. Diese sendet er dann zum Server. Im Connection-Handler siehst du, das die empfangene Zeile vom Client einfach ausgegeben wird, auch hier wieder in einer Endlosschleife.

Üblicherweise sendet ein Client ein bestimmtes Kommando zum Server, so das dieser erkennen kann, das der Client seine Verbindung beenden möchte. Beide (Client und Server) können dann ihre Verbindungen entsprechend updaten und der Server beispielsweise den Thread beenden.


----------



## dng (7. Jul 2014)

ok, danke, und veilen dDnk fuer deine Hilfe.ich verstehe besser.

Ich moechte ein command von Cleint zu Server insofern senden:
Client ->sendet-> message:Message

Server->bestaetigt der Empfang nicht
und dannn

Server->sendet an alle Client ->message :NAME:MESSAGE

Hat jemand eine Idee von der Algorithm


Danke


mfg dng


----------



## Anti-Banane (8. Jul 2014)

du willst also einen einfach chat basteln ... dann nutz bitte die sufu oder google ... es wurden hier schon unzählige besipiele gepostet wie sowas "mal eben schnell" umsetzbar ist
und google liefert auch teilweise sehr schöne erklärungen was da unter der haube so alles passiert das man es auch nachvollziehen kann



so n BISSCHEN eingeninitiative sollte man schon haben wenn man programmieren will


----------

