Allgemeine Frage zu Server/Client

4by4

Mitglied
Hey leute, weiß jetzt net ob das der richtige ort für den beitrag ist.
Hab eine allgemeine frage zu Server und Client.
Programmier technisch funktionieren beide. Möchte nur die "richtige" lösung anwenden.

Ich habe einen Server (ServerSocket/Java) und zwei Clients (Socket/Java).
Nachdem sich die Clients verbunden haben werden verschiedene befehle zum Server geschickt, dabei soll auch der zweite Client informiert werden.
Wie sollte ich jetzt "richtig" vorgehen.

Bsp. 1
1. Client1/Client2 sendet ein befehl an server
2. Server macht die änderung
3. Server informiert Client2/Client1

Bsp 2
1. Client1/Client2 sendet ein befehl an Server
2. Server macht die änderung
3. Client2/Client1 fragt in bestimmten abständen ob es eine änderung gegeben hat
4. Falls ja, server schickt dem client die änderung

Danke für die Hilfe
 

vfl_freak

Premium-User
Moin,

das hängt wohl vom Aufbau der Programme ab ....

Bestehen vom Server zu den Clients dauerhafte Verbindungen oder nur auf Anforderung?
Kann der Server überhaupt selbstständig Verbindungen zu anderen Clients aufbauen?
Reichen denn "bestimmte Abstände" aus?
Was ist der Zweck des Ganzen ??

Gruß
Klaus
 

Improof

Erfahrenes Mitglied
Hi 4by4,

das ist eine gute Frage und kommt meiner Meinung nach darauf an, was dir besser gefällt bzw. wie du dein Programm designed hast.
Ich nenn mal auf die Schnelle paar Vorteile (+) und Nachteile (-) beider Varianten:

Zu Bsp. 1
+ Wenn lange Zeit keiner der Clients etwas an den Server schickt, gibt es keinen unnötigen Traffic
+ Wenn ein Client einen Befehl sendet, werden alle anderen Clients unmittelbar darüber informiert
- Teilweise großes Durcheinander an Anfragen bzw. Datenverkehr
- Wenn viele Clients angemeldet sind immer viel Traffic auf einmal, da allen sofort eine Änderung gesendet wird
- Entfernt sich von der Technik von Webservern

Zu Bsp. 2
+ Anfragen kommen immer in gleichen Abständen
+ Traffic teilt sich auf, da immer nur der Client, der sich gerade meldet verarbeitet werden muss (nicht allen muss die Änderung auf einmal mitgeteilt werden, siehe oben)
+ Gleiches System wie bei Webservern: Ein Webserver kann nicht einfach etwas an einen Client (Browser) senden, sondern nur auf dessen Anfrage antworten
- Auch wenn lange Zeit kein Befehl gesendet wird, ergo, keine Änderung passiert, gibt es immer Traffic, weil die Clients Anfragen stellen
- Je nachdem, wie groß die Abstände sind, kann es dauern, bis alle Clients den neuen Stand kennen (z.B. 5 Sekunden Abstand = max. 5 Sekunden bis zum Update, wenn die Änderung kurz nach dem letzten Update kommt)

Auch wenn das jetzt so aussieht, also würde es insgesamt eher für Bsp. 2 sprechen:
Das waren jetzt 1. nur die Punkte, die mir spontan eingefallen sind und 2. kommt es letztendlich auf dein Design an und was die Applikation eigentlich genau macht.


Gruß
Daniel
 

4by4

Mitglied
Ich poste jetzt mal doch bisl Code, ich hab noch nix wirklich programmiert, bin erst in der Planung.
Meine idee ist, dass mehrere Geräte auf dem Rasperry eine Led bzw ein GPIO ein/ausschalten/status abfragen können.

Hab jetzt schnell was programmiert, bin eben erst in der Planung.

Die Klasse LED gibt es später nicht. Hab die nur als "Testklasse" angelegt.

Server
Java:
package server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import client.Client;

public class Server extends Thread {

    private int port;
    private boolean running;
    private ServerSocket server;

    // Testklasse
    private LED led;

    public Server(int port) {
        this.port = port;
        this.running = true;
        this.led = new LED();
    }

    @Override
    public void run() {
        try {
            server = new ServerSocket(port);
            while (running) {
                System.out.println("Server gestartet (port: " + port + ")...");
                System.out.println("Server: Warte auf Client(s)");
                new ServerHandler(server.accept(), led).start();
                System.out.println("Server: Client verbunden");
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        int port = 2000;
        String ip = "localhost";

        // Server wird gestartet
        new Server(port).start();
        // Client wird gestartet
        new Client(ip, port).start();
    }

}

class ServerHandler extends Thread {

    private ObjectInputStream in;
    private ObjectOutputStream out;
    private boolean running;
    private LED led;
    private Socket client;

    public ServerHandler(Socket client, LED led) throws IOException {
        this.client = client;
        this.out = new ObjectOutputStream(client.getOutputStream());
        this.in = new ObjectInputStream(client.getInputStream());
        System.out.println("Server: Streams geöffnet");
        this.running = true;
        this.led = led;
    }

    @Override
    public void run() {
        do {
            try {
                // Zurzeit nehme ich an dass nur Strings gesendet werden
                String str = (String) this.in.readObject();
                if (str.equals("LED1 aus")) {
                    if (led.getLed1status()) {
                        led.setLed1status(false);
                        writeObject("LED 1 ausgeschaltet");
                    } else {
                        writeObject("LED 1 ist bereits aus");
                    }
                } else if (str.equals("LED1 ein")) {
                    if (led.getLed1status()) {
                        writeObject("LED 1 ist bereits ein");
                    } else {
                        led.setLed1status(true);
                        writeObject("LED 1 eingeschaltet");
                    }
                } else if (str.equals("LED1 status")) {
                    if (led.getLed1status()) {
                        writeObject("LED 1 ein");
                    } else {
                        writeObject("LED 1 aus");
                    }
                } else if (str.equals("quit")) {
                    writeObject("Verbindung wird beendet");
                    this.running = false;
                    this.out.close();
                    this.in.close();
                    this.client.close();
                } else {
                    writeObject("Falscher Befehl");
                }
            } catch (ClassNotFoundException | IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } while (running);
    }

    private void writeObject(Object o) throws IOException {
        this.out.writeObject(o);
        this.out.flush();
    }

}

Client
Java:
package client;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

public class Client extends Thread {

    private String ip;
    private int port;
    private boolean running;
    private Socket client;
    private ObjectInputStream in;
    private ObjectOutputStream out;

    private String[] sende = { "LED1 aus", "LED1 status", "LED1 ein",
            "asdasda", "LED1 aus", "LED1 staturs", "LED1 aus", "LED1 ein",
            "quit" };

    public Client(String ip, int port) {
        this.ip = ip;
        this.port = port;
        this.running = true;
    }

    @Override
    public void run() {
        try {
            System.out.println("Client gestartet...");
            client = new Socket(ip, port);
            System.out.println("Client: Server gefunden");
            in = new ObjectInputStream(client.getInputStream());
            out = new ObjectOutputStream(client.getOutputStream());
            System.out.println("Client: Streams geöffnet");
            int i = 0;
            while (running) {
                writeObject(sende[i]);
                String s = (String) this.in.readObject();
                System.out.println("Client: " + s);
                if (sende[i].equals("quit")) {
                    running = false;
                    in.close();
                    out.close();
                    client.close();
                } else {
                    i++;
                }
            }
        } catch (IOException | ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private void writeObject(Object o) throws IOException {
        this.out.writeObject((String) o);
        this.out.flush();
    }
}

Jetzt müsst ich eben wissen wie ich ein update an die Clients sende.

Ich weiß dass ich später, nachdem sich mehrere Clients verbinden mit Lock und Condition arbeiten muss.
 
Zuletzt bearbeitet:

Neue Beiträge