Socket Client empfängt nur eigene Text-Eingaben

purzel

Bekanntes Mitglied
Hallo,

ich habe 2 Probleme! Erstens, warum wird die Methode
Code:
public void run()
(Client) nicht aufgerufen? Habe die Klasse um Thread erweitert?

2. Warum empfängt der Client nur seine eigenen Eingaben und nicht alle anderen auch? Ist das ein Server- oder Clientproblem?

Hier der Code (ja ich weiß, ist noch verbesserungsbedürftig - mir gehts aber erstmal ums Prinzip):

Server:
Java:
package name.purzel;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

public class Chat_Server {
	public static final int PORT = 8765;
	//public static final String HOST = "localhost";
	public static final String HOST = "masterpurzel.dyndns-server.com";
	public static String USERNAME = "tester85";
	static JFrame f;
	static JMenuBar menu;
    static JMenu menu_file;
    static JMenu menu_help;
    static JMenuItem menuItem_settings;
    static JMenuItem menuItem_exit;
    static JMenuItem menuItem_faq;
    static JMenuItem menuItem_about;
    static JButton connect;
    static JButton disconnect;
    static JLabel status;
    static ServerSocket server;
    static Socket s;
	
	public static void main(String[] args) {
		/*
		 * Layout
		 */
		f = new JFrame("Java Chat-Server");
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setSize(750, 450);
		
		/*
		 * Menü Anfang
		 */
		menu = new JMenuBar();
        menu_file = new JMenu("File");
        menu_help = new JMenu("Help");
        menuItem_settings = new JMenuItem("Settings");
        menuItem_settings.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
			}
		});
        menuItem_exit = new JMenuItem("Exit");
        menuItem_exit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					server.close();
				} catch (IOException se) {
					se.printStackTrace();
				} finally {
					System.exit(0);
				}
			}
		});
        menuItem_faq = new JMenuItem("F.A.Q.");
        menuItem_faq.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
			}
		});
        menuItem_about = new JMenuItem("About");
        menuItem_about.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
			}
		});
        menu.add(menu_file);
        menu.add(menu_help);
        menu_file.add(menuItem_settings);
        menu_file.add(menuItem_exit);
        menu_help.add(menuItem_faq);
        menu_help.add(menuItem_about);
        /*
         * Menü Ende
         */
		
		f.setLayout(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();
		
		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 0;
		c.gridx = 0;
		c.gridy = 0;
		c.gridwidth = 1;
		f.add(menu, c);
		
		connect = new JButton("Connect");
		connect.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				connect.setEnabled(false);
				disconnect.setEnabled(true);
				status.setText("Connected");
				try {
					server = new ServerSocket(PORT);
					new Thread(new Runnable() {
						public void run() {
							s = new Socket();
							while(!s.isClosed()) {
								try {
									s = server.accept();
								} catch (IOException e) {
									e.printStackTrace();
									break;
								}
								ServerThread t = new ServerThread(s);
								t.start();
								
							}
						}
					}).start();
				} catch (IOException se) {
					se.printStackTrace();
				}
			}
		});
		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 0;
		c.gridx = 0;
		c.gridy = 1;
		c.gridwidth = 1;
		f.add(connect, c);
		
		disconnect = new JButton("Disconnect");
		disconnect.setEnabled(false);
		disconnect.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				connect.setEnabled(true);
				disconnect.setEnabled(false);
				status.setText("Disconnected");
				try {
					server.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		});
		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 0;
		c.gridx = 1;
		c.gridy = 1;
		c.gridwidth = 1;
		f.add(disconnect, c);
		
		status = new JLabel("Disconnected");
		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 0;
		c.gridx = 0;
		c.gridy = 2;
		c.gridwidth = 1;
		f.add(status, c);
		
		f.pack();
		f.setVisible(true);
		
		new Chat_Server();
	}
}

ServerThread:
Java:
package name.purzel;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

public class ServerThread extends Thread {
	public Socket s;
	BufferedReader in;
	String text;
	BufferedWriter out;
	
	public ServerThread(Socket s) {
		this.s = s;
	}
	
	public void run() {
		try {
			in = new BufferedReader(new InputStreamReader(s.getInputStream()));
			while((text = in.readLine()) != null) {
				try {
					out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
					out.write(s + ": "+ text);
					out.newLine();
					out.flush();
					if(s.isClosed()) {
						in.close();
						out.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

Client:
Java:
package name.purzel;

import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class Chat_Client extends Thread {
	static String HOST = "masterpurzel.dyndns-server.com";
	static int PORT = 8765;
	static JFrame f;
	static JMenuBar menu;
    static JMenu menu_file;
    static JMenu menu_help;
    static JMenuItem menuItem_settings;
    static JMenuItem menuItem_exit;
    static JMenuItem menuItem_faq;
    static JMenuItem menuItem_about;
    static JTextArea output;
    static JTextField input;
    public static String text;
    public static String text2;
    public static Socket s;
    public static BufferedWriter out;
    public static BufferedReader in;
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		/*
		 * Layout
		 */
		f = new JFrame("Java Chat-Client");
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setSize(750, 450);
		
		/*
		 * Menü Anfang
		 */
		menu = new JMenuBar();
        menu_file = new JMenu("File");
        menu_help = new JMenu("Help");
        menuItem_settings = new JMenuItem("Settings");
        menuItem_settings.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
			}
		});
        menuItem_exit = new JMenuItem("Exit");
        menuItem_exit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});
        menuItem_faq = new JMenuItem("F.A.Q.");
        menuItem_faq.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
			}
		});
        menuItem_about = new JMenuItem("About");
        menuItem_about.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
			}
		});
        menu.add(menu_file);
        menu.add(menu_help);
        menu_file.add(menuItem_settings);
        menu_file.add(menuItem_exit);
        menu_help.add(menuItem_faq);
        menu_help.add(menuItem_about);
        /*
         * Menü Ende
         */
		
		f.setLayout(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();
		
		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 0;
		c.gridx = 0;
		c.gridy = 0;
		c.gridwidth = 1;
		f.add(menu, c);
		
		output = new JTextArea(35, 60);
		JScrollPane scrollbar = new JScrollPane(output);
		output.setFont(new Font("Dialog", Font.PLAIN, 12));
		output.setEditable(false);
		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 0;
		c.gridx = 0;
		c.gridy = 1;
		c.gridwidth = 1;
		f.add(scrollbar, c);
		
		input = new JTextField();
		input.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				text = input.getText().toString().trim();
				if(text != null || !text.equals("") || !text.isEmpty()) {
					try {
						out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
						out.write(text);
						out.newLine();
						out.flush();
						input.setText("");
					} catch (UnknownHostException e1) {
						e1.printStackTrace();
					} catch (IOException e1) {
						e1.printStackTrace();
					} catch(NullPointerException e1) {
						e1.printStackTrace();
					}
				}
			}
		});
		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 0;
		c.gridx = 0;
		c.gridy = 2;
		c.gridwidth = 1;
		f.add(input, c);
		
		f.pack();
		f.setVisible(true);
		
		new Chat_Client();
	}
	
	public Chat_Client() {
		try {
			s = new Socket(HOST, PORT);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		new Thread(new Runnable() {
			public void run() {
				try {
					in = new BufferedReader(new InputStreamReader(s.getInputStream()));
					while((text2 = in.readLine()) != null) {
						text2 = text2.trim();
						output.append(text2 + "\n");
						//System.out.print("Received: ");
						//System.out.println(text2);
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}).start();
	}
	
	public void run() { //geht nicht, warum?
		try {
			in = new BufferedReader(new InputStreamReader(s.getInputStream()));
			while((text2 = in.readLine()) != null) {
				text2 = text2.trim();
				output.append(text2);
				System.out.print("Received: ");
				System.out.println(text2);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
 
Ich vermute die Methode wird nirgens aufgerufen und daher auch nicht ausgeführt.

Die implementierung des Chatservers hast du nicht gepostet.

Nur die GUI dazu aber die ist eher uninteressant.
 
Zu 1:
Der Thread wird nirgens gestartet, erreichen kann man dies durch aufruf von
Code:
start();
.

Zu 2:
Weswegen sollen alle Clients die Nachricht erhalten? In der Klasse "ServerThread" wird doch lediglich die Nachricht an den Client zurückgesendet.
Eine Mögliche Lösung wäre eine Liste in der Klasse "Server" zu erstellen in die alle Verbundenen Clients hinzugefügt werden, somit könnte man über eine entsprechende Methode die Liste durchgehen und jedem Client eine Nachricht senden.
 
Erstens, warum wird die Methode
Code:
public void run()
(Client) nicht aufgerufen? Habe die Klasse um Thread erweitert?

Weil du nirgends start() aurfust, zumindest nicht auf dem Thread-Objekt welches du in Zeile 146
Code:
new Chat_Client();
erstellst. Was soll das überhaupt werden, wieso erweiterst du einmal die Klasse als Thread (ist sowieso eher häßlich) und einmal erstellst du im Konstruktor noch einmal einen Thread?! Und generell ist das alles sehr durcheinander, trenne doch mal übersichtlich GUI, Controller und Model (falls vorhanden)

2. Warum empfängt der Client nur seine eigenen Eingaben und nicht alle anderen auch? Ist das ein Server- oder Clientproblem?

Wenn ich das auf die Schnelle richtig gesehen habe, dann wohl ein Server Problem. Ich finde jetzt zumindest spontan nichts, wo der Server die Nachricht an alle Clients weiter reicht/verteilt ?!
 
Zu 1:
Der Thread wird nirgens gestartet, erreichen kann man dies durch aufruf von
Code:
start();
.

OK, danke das hat gefehlt :rtfm:

Zu 2:
Weswegen sollen alle Clients die Nachricht erhalten? In der Klasse "ServerThread" wird doch lediglich die Nachricht an den Client zurückgesendet.
Eine Mögliche Lösung wäre eine Liste in der Klasse "Server" zu erstellen in die alle Verbundenen Clients hinzugefügt werden, somit könnte man über eine entsprechende Methode die Liste durchgehen und jedem Client eine Nachricht senden.

Danke für den Tipp, werde es morgen mal versuchen einzubauen.
 
warum ein server-dienst eine GUI braucht verschweigt sich mir ...

Naja es ist ja nicht nur das starten und stoppen des Dienstes, sondern noch mehr. Zum Beispiel die Anzeige der aktuellen User im Chat etc. Ist ja nur der Anfang...

gutes tutorials zum thema java-chat

Kaffee & Kuchen - Datenbank-Anbindung mit JDBC

hätte dich google auch hingebracht

komisch die Seite fand ich bei mir in google nicht :bahnhof: - Aber Danke 🙂
 
Gibt es eine Möglichkeit ein
Code:
ArrayList<Object>()
zu ein oder mehrere Socket zu zerteilen? Konnte nichts finden!
 
HÄÄ ?

vielleicht solltest du uns erstmal erklären was in dieser List<?> überhaupt gespeichert wird und was du dann damit machen willst ...

aus deinem post geht weder das eine noch das andere hervor
 
ALSO,

  1. Was wird darin gespeichert
  2. Was soll damit erreicht werden

zu 1.) ich habe inzwischen eine etwas bessere Speichermethode gefunden:
Code:
ArrayList<Socket>
, dann leuchtet bei euch bestimmt etwas auf 😉 Da sind meine Socket/Clientverbindungen gespeichert...

zu 2.) Ich speichere Sockets/Clients in die Liste und will dann die Nachrichten an alle in der Liste verfügbaren Verbindungen senden

Soweit verständlich?

Falls weitere Unklarheiten sind, könnt Ihr mich ruhig löchern 😀
 
Wie weiter oben schon geschrieben kann man nun durch die Liste gehen und jedem die Nachricht senden, wo genau kommst du da nicht weiter?
 
Ich habe es vesucht mit
Code:
for(int i = 0;i < sockets.size(); i++) {...}
dann geht aber nur noch der erste Client. Die anderen können nichts mehr senden oder empfangen 🙁 Was mache ich falsch, oder ist hier
Code:
for()
falsch?

€dit: wenn ich Client1 beende erscheint die meldung von Client2 auf Client2...

Mh, da ist irgendwie der Wurm drin

ServerThread
Java:
package name.purzel;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.ArrayList;

public class ServerThread extends Thread {
	public Socket s;
	ArrayList<Socket> clients;
	Socket client;
	BufferedReader in;
	String text;
	BufferedWriter out;
	
	public ServerThread(Socket s) {
		this.s = s;
	}
	
	public ServerThread(ArrayList<Socket> clients) {
		this.clients = clients;
	}
	
	public void run() {
		for(int i = 0; i < clients.size(); i++) {
			try {
				in = new BufferedReader(new InputStreamReader(clients.get(i).getInputStream()));
				while((text = in.readLine()) != null) {
					try {
						out = new BufferedWriter(new OutputStreamWriter(clients.get(i).getOutputStream()));
						out.write(clients.get(i) + ": "+ text);
						out.newLine();
						out.flush();
						if(clients.get(i).isClosed()) {
							in.close();
							out.close();
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			} catch(NullPointerException e) {
				e.printStackTrace();
			}
		}
	}
}
 
Zuletzt bearbeitet:
Wenn ich jetzt im Client1 text eingebe erscheint er auf Client1 & Client2, wenn ich allerdings im Client2 text eingebe erscheint er nirgends...

ServerThread
Java:
package name.purzel;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;

public class ServerThread extends Thread {
	public Socket s;
	ArrayList<Socket> clients;
	Socket client;
	BufferedReader in;
	String text;
	BufferedWriter out;
	
	public ServerThread(Socket s) {
		this.s = s;
	}
	
	public ServerThread(ArrayList<Socket> clients) {
		this.clients = clients;
	}
	
	@SuppressWarnings("rawtypes")
	public void run() {
		for(int i = 0; i < clients.size(); i++) {
			try {
				in = new BufferedReader(new InputStreamReader(clients.get(i).getInputStream()));
				while((text = in.readLine()) != null) {
					Iterator iter = clients.iterator();
			        while(iter.hasNext() ) {
			            Object o = iter.next();
			            System.err.println(o + ": " + text);
			            try {
							out = new BufferedWriter(new OutputStreamWriter(((Socket) o).getOutputStream()));
							out.write(o + ": "+ text);
							out.newLine();
							out.flush();
							if(((Socket) o).isClosed()) {
								in.close();
								out.close();
							}
						} catch (IOException e) {
							e.printStackTrace();
						}
			        }
					
				}
			} catch (IOException e) {
				e.printStackTrace();
			} catch(NullPointerException e) {
				e.printStackTrace();
			}
		}
	}
}

Wo liegt mein DENKfehler?

Danke schon mal für die Mühe 🙂
 
Wie sieht deine Server-Klasse derzeit aus?

So wie ich das sehe versuchst du das versenden der Nachricht in der ServerThread-Klasse, dies sollte jedoch in der Server-Klasse stattfinden (entsprechende Get-Methode für den Outputstream im ServerThread anlegen).

Schöne Beispiele dafür findest du auch in den beiden genannten Links.
 
Wie sieht deine Server-Klasse derzeit aus?

So sieht sie aus:

Java:
package name.purzel;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

public class Chat_Server {
	public static final int PORT = 8765;
	//public static final String HOST = "localhost";
	public static final String HOST = "masterpurzel.dyndns-server.com";
	public static String USERNAME = "tester85";
	static JFrame f;
	static JMenuBar menu;
    static JMenu menu_file;
    static JMenu menu_help;
    static JMenuItem menuItem_settings;
    static JMenuItem menuItem_exit;
    static JMenuItem menuItem_faq;
    static JMenuItem menuItem_about;
    static JButton connect;
    static JButton disconnect;
    static JLabel status;
    static ServerSocket server;
    static Socket s;
    static ArrayList<Socket> clients = new ArrayList<Socket>();
	
	public static void main(String[] args) {
		/*
		 * Layout
		 */
		f = new JFrame("Java Chat-Server");
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setSize(750, 450);
		
		/*
		 * Menü Anfang
		 */
		menu = new JMenuBar();
        menu_file = new JMenu("File");
        menu_help = new JMenu("Help");
        menuItem_settings = new JMenuItem("Settings");
        menuItem_settings.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
			}
		});
        menuItem_exit = new JMenuItem("Exit");
        menuItem_exit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					server.close();
				} catch (IOException se) {
					se.printStackTrace();
				} finally {
					System.exit(0);
				}
			}
		});
        menuItem_faq = new JMenuItem("F.A.Q.");
        menuItem_faq.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
			}
		});
        menuItem_about = new JMenuItem("About");
        menuItem_about.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
			}
		});
        menu.add(menu_file);
        menu.add(menu_help);
        menu_file.add(menuItem_settings);
        menu_file.add(menuItem_exit);
        menu_help.add(menuItem_faq);
        menu_help.add(menuItem_about);
        /*
         * Menü Ende
         */
		
		f.setLayout(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();
		
		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 0;
		c.gridx = 0;
		c.gridy = 0;
		c.gridwidth = 1;
		f.add(menu, c);
		
		connect = new JButton("Connect");
		connect.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				connect.setEnabled(false);
				disconnect.setEnabled(true);
				status.setText("Connected");
				try {
					server = new ServerSocket(PORT);
					new Thread(new Runnable() {
						public void run() {
							s = new Socket();
							while(!s.isClosed()) {
								try {
									s = server.accept();
									clients.add(s);
								} catch (IOException e) {
									e.printStackTrace();
									break;
								}
								//ServerThread t = new ServerThread(s);
								//t.start();
								ServerThread ct = new ServerThread(clients);
								ct.start();
							}
						}
					}).start();
				} catch (IOException se) {
					se.printStackTrace();
				}
			}
		});
		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 0;
		c.gridx = 0;
		c.gridy = 1;
		c.gridwidth = 1;
		f.add(connect, c);
		
		disconnect = new JButton("Disconnect");
		disconnect.setEnabled(false);
		disconnect.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				connect.setEnabled(true);
				disconnect.setEnabled(false);
				status.setText("Disconnected");
				try {
					server.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		});
		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 0;
		c.gridx = 1;
		c.gridy = 1;
		c.gridwidth = 1;
		f.add(disconnect, c);
		
		status = new JLabel("Disconnected");
		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 0;
		c.gridx = 0;
		c.gridy = 2;
		c.gridwidth = 1;
		f.add(status, c);
		
		f.pack();
		f.setVisible(true);
		
		new Chat_Server();
	}
}

Ok, Danke schon mal, muss dann mal morgen drin schmökern 😉 - jetzt bin ich dazu zu müde
 
ich würde dir auch empfehlen den GUI-kram erstmal weg zu lassen da bei dir noch nicht mal die grundlagen eines chat-systems fehlerfrei funktionieren ...

ich hab mir mal die mühe gemacht und für dich ein *wenn auch nicht so optimales und sauberes aber funktionsfähiges* beispiel geschrieben

Server
Java:
import java.io.*;
import java.net.*;
import java.util.*;
public class Server extends Thread
{
	private ServerSocket serverSocket;
	private List<ServerThread> clientList;
	public static void main(String[] args) { (new Server()).start(); }
	private Server()
	{
		try
		{
			serverSocket=new ServerSocket(30000);
		}
		catch(Exception e) { e.printStackTrace(); System.exit(1); }
		clientList=new ArrayList<ServerThread>();
	}
	public void run()
	{
		while(true)
		{
			try
			{
				Socket clientSocket=serverSocket.accept();
				ServerThread thread=new ServerThread(this, clientSocket);
				clientList.add(thread);
				thread.start();
			}
			catch(Exception e) { e.printStackTrace(); }
		}
	}
	protected void broadcast(String msg)
	{
		for(ServerThread thread : clientList)
		{
			thread.send(msg);
		}
	}
	protected void disconnect(ServerThread thread)
	{
		clientList.remove(thread);
	}
}

ServerThread
Java:
import java.io.*;
import java.net.*;
class ServerThread extends Thread
{
	private Server server;
	private Socket socket;
	private BufferedReader in;
	private PrintStream out;
	private String line;
	protected ServerThread(Server server, Socket socket)
	{
		this.server=server;
		this.socket=socket;
	}
	public void run()
	{
		try
		{
			in=new BufferedReader(new InputStreamReader(socket.getInputStream()));
			out=new PrintStream(socket.getOutputStream());
		}
		catch(Exception e)
		{
			e.printStackTrace();
			try
			{
				in.close();
				out.close();
				socket.close();
				server.disconnect(this);
			}
			catch(Exception e2) { e.printStackTrace(); }
			return;
		}
		while(true)
		{
			try
			{
				line=in.readLine();
				if((line==null)||(line.equalsIgnoreCase("quit")))
				{
					break;
				}
				if(!line.equals(""))
				{
					server.broadcast(line);
				}
			}
			catch(Exception e) { e.printStackTrace(); break; }
		}
		try
		{
			in.close();
			out.close();
			socket.close();
			server.disconnect(this);
		}
		catch(Exception e) { e.printStackTrace(); }
	}
	protected void send(String msg)
	{
		try
		{
			out.println(msg);
		}
		catch(Exception e) { e.printStackTrace(); }
	}
}

ich weis das man daran noch so einiges verbessern kann ... aber es funktioniert so weit erstmal *GETESTET !* und macht das was ein chat-server machen soll : die nachricht von einem user an alle anderen weiterleiten ...

ich habe den code jetzt mal nicht kommentiert *das wäre mir zu viel des guten gewesen* ... aber ich denke die grundlegende funktionsweise sollte ersichtlich sein ...

das ganze lässt sich sehr einfach erweitern ...

falls du irgendwann noch command-daten übertragen willst *z.b. user-liste* musst du natürlich darauf reagieren wenn ein user versucht entsprechende commands dierekt durch eingabe an den server zu senden *ich verwenden bei sowas immer "private" nachrichten das der eingegebenen text ungültig ist*

es ist im groben nicht viel anderst als das beispiel von Kaffee & Kuchen - die fhrende Java-Seite Deutschlands (Neu) ... vielleicht etwas auf den neuen stand gebracht *deprecated klassen und methoden behoben* ... aber vom grundprinzip 1zu1 übernommen ...

versuche das mal als basis-kern für dein vorhaben zu verwenden und eine steuer-GUI drumherum zu bauen ...
 
was die "steuer-GUI" angeht bin ich bei deinem ansatz eh skeptisch ...

ich persönlich baue für sowas immer noch einen extra ServerSocket ein auf den man sich mit einem speziellen "admin-client" verbinden kann und so den server steuert ...
natürlich muss man dabei dafür sorgen das sich nur legitime remote-ip's verbinden können und auch eine auth einbauen falls jemand mit ip-spoof arbeitet ...

den server selbst mit einer GUI zu belasten halte ich nicht für sonderlich empfehlenswert ... zu mal dann der VM weniger resourcen für net-i/o zur verfügung stehen da sich intern noch um die GUI gekümmert werden muss ...
 
Hört sich gut an Dein Vorschlag! Versuche das dann mal umzusetzen mit der remote-console (gui). Wie setzt man am besten so eine auth um? Username und PW im QT oder ist es besser in einer db, obwohl eine db für sowas überdimensioniert wäre...
 
AM besten nimmt man ein Security Framework z.B. Spring Security.

Aber jedes "am besten" wäre überdimensioniert für dein Vorhaben.

Mach einfach Passwort im Quelltext. Hier wirst du auf ganz andere Probleme stoßen.
 
Mach einfach Passwort im Quelltext. Hier wirst du auf ganz andere Probleme stoßen.

kk ... dann hast DU vllt nicht wirklich verstanden wie ICH es meinte ...

da das AUTH-system NUR dem server und damit dessen programmiere bekannt ist kannst du das ganze schon dierekt in den source des servers schreiben ... da man diesen natürlich NICHT public machen sollte ...

auch sollte man die remote-gui nur via localhost *oder ggf über eine spezielle proxy-app* connecten lassen können ... *ist zumindest bei meinen servern so* ...

ob man da wirklich gleich mittem Spring-Framework drauflos gehen sollte halte ich jetzt aber mal von dir aus mehr als sogar maßlos übertrieben ... da sich *wenn man es richtig macht* eine einfache abfrage der "ersten" msg die man erhält als "kennwort-abfrage" durchaus eignet ... da muss man kein riesen framework und ne DB dahinter klemmen

*btw : wofür braucht man eigentlich SPRING ? so weit ich das bis jetzt hier gelesen hab ist es doch vielmehr ein großes DB-framework ... und da bietet java selbst alles was man braucht *zu mal SPRING selbst meines wissens in JAVA geschrieben ist* ...
wer sich also wirklich die mühe macht und eine ganzes framework einbindet nur um vllt ein paar DB abfragen zu machen sollte sich ganz stark über das konzept seiner app gedanken machen*
 
Vielen Dank für eure Antworten! Eine Frage hätte ich noch, bevor ich das hier schließe:

Kennt Ihr gute Bücher zur Netzwerkprogrammierung? (Kann auch englisch sein!).

LG Purzel
 
GooGLe

btw : bevor wer anfängt zu flamen : ich hab mich mal bissl mit SPRING befasst ... gut ja ... ist doch ein etwas umfangreicheres framework ... aber für sowas dann wirklich zu overkill
 
FAIL

@TO

genau das meinte ich eigentlich mit "GooGLe" ...

man sollte schon mal so viel eigeninitiative haben um sich auch mal fragen an google selbst auszudenken oder musst du dir wirklich jetzt noch verraten lassen was du bei google eingeben musst ...
 

Zurück
Oben