Archief - Java Chatapplicatie Sockets

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

*Fmc*

Legacy Member
Hallo,

Na enkele simpele chatapplicaties te maken, zou ik nu een app willen maken die berichten naar iedereen stuurt. Echter heb ik een probleem bij het bijhouden van de clients. Dit gebeurt in een Arraylist van een Runnable-klasse. Maar steeds wanneer ik wil broadcasten, geeft hij blijkbaar niets door aan de outputstream.

Hier is mijn voorlopige code.

ChatServer.java
Code:
public class ChatServer {
	private ServerSocket socket = null;
	private Socket conn = null;
	private ExecutorService threadService = null;

	
	public ChatServer() {
		try{
			socket = new ServerSocket(5432);
			threadService = Executors.newCachedThreadPool();
			while(true){
				conn = socket.accept();
				ClientConnection client = new ClientConnection(conn);
				threadService.execute(client);
			}
		}catch(IOException ex){
			ex.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		new ChatServer();
	}
}

ClientConnection.java
Code:
public class ClientConnection implements Runnable {

	private List<ClientConnection> clientList = new ArrayList<ClientConnection>();
	private Socket conn = null;
	private ObjectInputStream input = null;
	private ObjectOutputStream output = null;
	private Message message;

	public ClientConnection(Socket conn) {
		this.conn = conn;
		clientList.add(this);
	}

	@Override
	public void run() {
		try {
			while (true) {
				input = new ObjectInputStream(conn.getInputStream());
				Object object = input.readObject();
				if (object instanceof Message) {
					message = (Message) object;
					System.out.println(message.getBericht());
					broadcast();
				}
			}
		} catch (IOException ex) {
			ex.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	private void broadcast(){
		Iterator it = clientList.iterator();
		while(it.hasNext()){
			try {
				output = new ObjectOutputStream(conn.getOutputStream());
				output.writeObject(message);
				output.flush();
                                output.reset();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

ChatClient.java
Code:
public class ChatClient {
	
	private Socket conn = null;
	private ObjectInputStream input = null;
	private ObjectOutputStream output = null;
	private Message message = null;
	private Scanner scanner = null;
	
	public ChatClient() {
		try{
			conn = new Socket("127.0.0.1", 5432);
			scanner = new Scanner(System.in);
			String bericht = scanner.nextLine();
			while(true){
				message = new Message(bericht, "Pol");
				output = new ObjectOutputStream(conn.getOutputStream());
				output.writeObject(message);
				output.flush();
				bericht = scanner.nextLine();
				input = new ObjectInputStream(conn.getInputStream());
				Message message = (Message) input.readObject();
				System.out.println(message.getVerzender() + ": " + message.getBericht());
				output = new ObjectOutputStream(conn.getOutputStream());
			}
		}catch(IOException ex){
			ex.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}finally{
			scanner.close();
			try {
				input.close();
				output.close();
				conn.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) {
		new ChatClient();
	}

}

Wil bij ClientConnection een iterator gebruiken om later wanneer een client disconnect dit op te vangen.

Alvast bedankt!

EDIT: Ik zie precies al één fout. Ik lees de verzonden berichten niet uit op de client :p
Code even aangepast en nu krijg ik een error op die output.reset() denk ik.

Code:
java.net.SocketException: Software caused connection abort: socket write error
	at java.net.SocketOutputStream.socketWrite0(Native Method)
	at java.net.SocketOutputStream.socketWrite(Unknown Source)
	at java.net.SocketOutputStream.write(Unknown Source)
	at java.io.ObjectOutputStream$BlockDataOutputStream.drain(Unknown Source)
	at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(Unknown Source)
	at java.io.ObjectOutputStream.<init>(Unknown Source)
	at be.xios.chat.server.ClientConnection.broadcast(ClientConnection.java:49)
	at be.xios.chat.server.ClientConnection.run(ClientConnection.java:35)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)

Fraggie

Legacy Member
Als ik dit zo oppervlakkig bekijk mis ik de link tussen je broadcast functie in je ClientConnection en je Server. Je Server doet bijzonder weinig en je ClientConnection kent toch geen andere clients?

Ik heb dit waarschijnlijk al eerder gezegd, maar i.e. ben je opzoek naar: Observer pattern - Wikipedia, the free encyclopedia

*Fmc*

Legacy Member
Fraggie zei:
Als ik dit zo oppervlakkig bekijk mis ik de link tussen je broadcast functie in je ClientConnection en je Server. Je Server doet bijzonder weinig en je ClientConnection kent toch geen andere clients?

Ik heb dit waarschijnlijk al eerder gezegd, maar i.e. ben je opzoek naar: Observer pattern - Wikipedia, the free encyclopedia

Ik hou in de ClientConnection een list bij van ClientConnections en voeg dan in de constructor eentje toe aan de lijst.

De rest zal ik morgen is verder bekijken. Dit is echt een lastig onderwerp, vind ik :p

Fraggie

Legacy Member
*Fmc* zei:
Ik hou in de ClientConnection een list bij van ClientConnections en voeg dan in de constructor eentje toe aan de lijst.
Dat is niet wat er gebeurd.. Je wil dat misschien wel, maar dan moet je het anders gaan programmeren.

Kemblin

Legacy Member
Die lijst van clientconnections moet sowieso in de chatserver. Zoals hij nu in de ClientConnection klasse staat zal hij telkens maar 1 connection bevatten.

*Fmc*

Legacy Member
Ja, dat had ik intussen ook al ontdekt door ff die list naar de console te printen. Alvast bedankt voor de hulp. Heb er wel niet meer aan verder kunnen werken, maar ik denk dat ik nu wel weer verder kan.
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan