Client mit mehreren Aufgaben

Poehli

Mitglied
Hi,
ich habe jetzt ein weiteres Problem:
Wie kann man es bewerkstelligen, dass ein Client mehrere Befehle zum Server schicken kann?
Bzw. bekomme ich es nicht hin, dass der Server mehrere liest. Es müsste ja so gehen, dass der Server auf Befehle wartet, bis er den Exit befehl (oder wie auch immer) bekommen hat oder der Client sich "abmeldet".
Aber eine einfache While schleife führt nicht zu dem gewünschten Ziel, was ich nicht ganz verstehe.
Wäre gut, wenn einer von Euch ne Antwort kennt
 
Hi,

wie darf man diese Frage verstehen? Was meinst du mit mehreren Befehlen?

Wie kann man es bewerkstelligen, dass ein Client mehrere Befehle zum Server schicken kann?

Wenn mehrere Clients Befehle an den Server schicken, muss der Server für jeden Client einen Thread zu dessen Befehlsverarbeitung bereitstellen.

Gruß

Fabio
 
Geht auch ohne Thread-pro-Socket (mit denen man eher sparen sollte).
Sowas wie select etc. gibts ja zum Glück auch in Java (nio :google:)

@poehli: Etwas Code wäre nicht schlecht.
 
Ja wäre manchmal hilfreich :p
hier ist der Code mit noch fehlerhaften Versuchen:

Mehrere Clients hab ich mit dem folgenden Thread gemacht (funktioniert):
Code:
public class ClientThread extends Thread {

	private Socket so;
	private BufferedReader vomClient;
	private BufferedWriter zumClient;
	private TicTacToeController controller;
	private TicTacToeModel data;

	public ClientThread(Socket so) throws IOException {		
		this.so = so;

		this.data = new TicTacToeModel();
		this.controller = new TicTacToeController(data);
	}

	private void sendToClient(String spec) throws Exception {

		if (spec.equals("felder")){
			zumClient.write(data.getFelderAsString());
		}
		else if (spec.equals("runde")){
			zumClient.write(data.round);
		}
		else if (spec.equals("spiel")){
			zumClient.write(data.getGames());
		}
		else if (spec.equals("gegenspieler")){

			// Hier könnte noch ein Tokenizer benötigt werden
			Player otherPlayer = data.getInactivePlayer();
			zumClient.write(otherPlayer.name+" "+otherPlayer.color+" "+otherPlayer.active);
		} else {
			throw new Exception("Falsche Spezifikation des Kommandos GET");
		}

	}

	private void processFromClient(StringTokenizer spec){

		String next = spec.nextToken();
		if (next.equals("feld")){
			int feldIndex = Integer.parseInt(spec.nextToken());
			int color = Integer.parseInt(spec.nextToken());
			controller.updateFeld(feldIndex, color);
		}
		else if (next.equals("update-runde")){
			data.round += 1;
		}
		else if (next.equals("update-spiel")){
			data.addGame();
		}
		else if (next.equals("spieler")){
			int color = Integer.parseInt(spec.nextToken());


			// --- überprüfung der einzelnen Spieler Update Methoden

			if (spec.hasMoreTokens()){

				// Falls mehrere Rückgabewerte soll überprüft werden ob es ein true/ false ist oder der Name des Spielers (active und win update oder name update)
				String checkActive = spec.nextToken();
				if (checkActive.toLowerCase().equals("true") || checkActive.toLowerCase().equals("false")){
					String checkWin = spec.nextToken();
					boolean active;
					boolean win;

					// String Werte in boolean umwandeln
					if (checkActive.toLowerCase().equals("true"))
						active = true;
					else 
						active = false;

					// dasselbe für win
					if (checkWin.toLowerCase().equals("true"))
						win = true;
					else 
						win = false;

					// letztendlich methodenaufruf
					controller.updateSpieler(color, active, win);

				} else {
					controller.updateSpieler(color, checkActive);
				}
			} else {
				controller.updateSpieler(color);
			}

		}
	}


	private void waitForServer(BufferedReader vomClient) throws IOException {
		while (!vomClient.ready()){

		}
	}

	public void run(){
		try {


			vomClient = new BufferedReader(new InputStreamReader(so.getInputStream()));

			zumClient = new BufferedWriter(new OutputStreamWriter(so.getOutputStream()));

			try {
				while (true){
					waitForServer(vomClient);
					String kommandozeile = vomClient.readLine();

					System.out.println("Folgende Befehl: "+kommandozeile+" wurde vom User mit der IP "+so.getLocalSocketAddress()+" abgesetzt");


					StringTokenizer stok = new StringTokenizer(kommandozeile, " \r\n");
					String cmd = stok.nextToken();

					// Daten holen 
					if (cmd.equals("EMPFANGE")){
						String spec = stok.nextToken();
						sendToClient(spec);

						// Daten Senden
					} else if (cmd.equals("SENDE")){
						processFromClient(stok);
					} else if (cmd.equals("EXIT")){
						so.shutdownOutput();
						so.shutdownInput();
						so.close();
						zumClient.flush();
						this.stop();
					} else {
						throw new Exception("Unknown Command");
					}
				}
			} catch (Exception e){
				e.printStackTrace();
				System.out.println("Fehler!");
				new PrintWriter(zumClient).println("Fehler");
			}
			zumClient.flush();

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

der/ die clients mit zwei println Befehlen:

Code:
public class Client {

	/**
	 * @param args
	 * @throws IOException 
	 * @throws UnknownHostException  
	 */
	public static void main(String[] args) throws UnknownHostException, IOException{		
		String rechneradresse = args[0];
		String dateiname = args[1];

		
		System.out.println("verbinde mit server...");
		Socket so = new Socket(rechneradresse, 8181); 

		System.out.println("verbunden");
		BufferedReader vomServer = new BufferedReader(new InputStreamReader(so.getInputStream()));

		PrintWriter zumServer = new PrintWriter(new OutputStreamWriter(so.getOutputStream()));


		zumServer.println("EMPFANGE "+dateiname);
		zumServer.flush();
		System.out.println("waiting...");
		int c = vomServer.read();
		System.out.println("done.");
		while (c > -1){
			System.out.print((char) c);
			c = vomServer.read();
		}
		zumServer.println("EXIT");
		vomServer.close();
		so.close();
	}
}
 
Hab ich's mir doch gedacht ;)
Ich habe mir das so gedacht, dass ich einen Server habe, an den sich mehrere Clients anmelden können. Jeder dieser Clients wiederum soll mehrere "Befehle" absetzen können.
Bsp.:
Client A -> EMPFANGE daten, EXIT (Client erhält in der Rückgabe alle Daten und loggt sich dann aus)
Client B -> SENDE felder ..., EMPFANGE gegenspieler, EXIT (Client verändert irgendetwas von den Daten beim Server und erhält informationen zum Gegenspieler und loggt sich dann aus)

Der Server funktioniert in soweit, dass er EINEN Befehl pro Client annehmen kann (e.g. EMPFANGE gegenspieler) und auch die richtigen Daten an den Client zurücksendet.

Meine Überlegung dabei war, dass es an dem Server liegen muss, da beim Client (soweit ich weiß) nicht viel falsch sein kann. Aus dem Grund habe ich versucht eine einfache While-Schleife um meinen Try/Catch Block zu legen um die Abfrage nach einem Befehl unendlich oft durchlaufen zu lassen. Dies erzielt aber nicht den gewünschten Effekt.

Ich hoffe ich konnte jetzt einigermaßen klar machen, um was es geht.
 
Wir kommen näher.
Jetzt wäre noch der Teil vom Server schön, wo die Verbindung angenommen
und der Clientthread gestartet wird.

Und hast du mal geprüft, was bei einer Verbindung ausgeführt wird?

Bzw. woran äußert sich das überhaupt, dass es nicht geht?
Hängts, verweigert die Verbindung...?
 
Code:
public class Server{
	
	public void startServer() throws IOException{
		System.out.println("Starte Server...");
		ServerSocket serverso = new ServerSocket(8181);

		System.out.println("Warte auf Client...");
		while(true){ 
			
			Socket so = serverso.accept();
			Thread client = new ClientThread(so);
			client.start();
			System.out.println("Warte auf Client...");
		}
	}
}

(auch wenn ich nicht verstehe wofür du den brauchst :p )
 
(auch wenn ich nicht verstehe wofür du den brauchst :p )
Weil erfahrungsgemäß die Mehrheit der Leute mit ähnlichen Problemen den Fehler dort hatten :p

Bei dir scheint aber alles Übliche zu passen.
Du versuchst nicht, von serverso Daten zu empfangen etc. :D


Hab oben noch eine Frage reineditiert, während du schon gepostet hast:
Und hast du mal geprüft, was bei einer Verbindung ausgeführt wird?

Bzw. woran äußert sich das überhaupt, dass es nicht geht?
Hängts, verweigert die Verbindung...?
 

Neue Beiträge

Zurück