Ich habe einen Server und einen Client.
Der Server schickt eine Zahl ab und der Client printet sie aus.
Also so einfach wie nur irgend möglich.
Wenn ich jetzt aber einen 2. Client starte kommt die Zahl dort nicht mehr an.
Wie kann ich das ändern?
- Server wartet auf Verbindungsanfragen
- Client meldet sich beim Server an
- Server startet einen Thread (ClientHandler) der sich um den Client kümmert
- Den Clienthandler merkt sich der Server in einer Liste
- Server wartet wieder auf Verbindungsanfragen
Wenn der Server jetzt was senden will dann geht er seine Liste durch und schickt die daten an jedem einzelnen Client.
Wie oben erwähnt, ist es notwendig, für jeden Client einen eigenen Thread zu eröffnen. Dadurch kann der Sever auf weitere Anfragen warten und gleichzeitig die bereits vorhandenen Clients versorgen. Du musst nur beachten, dass du die Annahme der Anfragen in eine Schleife packst, die so lange aktiv ist, so lange der Server bereit für Anfragen ist. Wenn du das nicht machst, würde zwar der erste Client einen Thread bekommen, danach würde der Server aber nicht mehr in den Zustand des Abhörens zurück gelangen.
Ich nehme mal an dass er sich einen eigenen Server und Client programmiert hat.
@Loud Silence: Am besten ließt du in der entsprechenden Literatur/auf Internetseiten nach, wie man in Java mit Threads arbeitet.
Hier bspw: Threads in Java
Ich arbeite mit einem selbstgemachten Client/Server.
Die Funktionen sind oben beschrieben.
Des weiteren sind sowohl schreiben als auch lesen bereits in einem eigenen Thread ausgelagert.
Ich weiß nur nicht was ich genau in den Thread zum Anfragen bearbeiten schreiben soll.
Dann brauchst du eigentlich keinen Thread mehr für das Annehmen der Anfragen, wenn sich das schon im Hauptprogramm befindet. An und für sich müsste es reichen, wenn du die Annahme jetzt in eine endlos-Schleife packst (die natürlich auf Abbruchbedingungen hört), damit das Programm immer wieder zu
server.accept(); und thread.start(); zurückkommt. Vllt postet du mal einen Codeausschnitt hier rein?
publicvoidrun(){try{System.out.println("Neue Verbindung zu Client");
out =newBufferedWriter(newOutputStreamWriter(s.getOutputStream()));Scanner scanner =newScanner(System.in);while(!(msg = scanner.nextLine()).equalsIgnoreCase("end")){sendMessage(msg);// Methode nicht mit angegeben; ist selbsterklärend}
Client lesen starten:
Java:
Client()throwsIOException{Socket server =newSocket("localhost",1234);ClientReadingThread st =newClientReadingThread(server);
st.start();}
Möglicherweise liegt es daran, dass du in jedem senden-Thread einen eigenen Scanner hast. Diese wechseln sich dann mit dem Abhören der Eingabe ab, sodass jede Eingabe immer nur zu je einem Thread gehört und du die Eingabe damit auch nur zu nur einem Client schickst. Da bin ich mir aber nicht ganz sicher, es kann auch sein dass es unerheblich ist, welcher Scanner die Eingabe 'gefordert' hat, und immer alle Scanner die Eingabe entgegen nehmen (habs jetzt nicht getestet). Probier darher mal, nur einen Scanner bereits in der "KleinerServer()" Methode zu erzeugen, und ihn den ServerSendingThread-Objekten zu übergeben und dort damit zu arbeiten.
Falls es das nicht ist, weiß ich auch nicht. Hab sonst keinen potentiellen Fehler gefunden.
Das hat einen nicht so tollen Effekt:
Ich muss alles sooft eingeben wie Clients vorhanden sind.
Wenn drei Clients geöffnet sind muss ich drei mal dasselbe eingeben.
Aber es wird dann auch an alle geschrieben.
Allerdings spuckt die Konsole einen Fehler aus:
Exception in thread "Thread-3" java.lang.IndexOutOfBoundsException: end
at java.util.regex.Matcher.region(Unknown Source)
at java.util.Scanner.findPatternInBuffer(Unknown Source)
at java.util.Scanner.findWithinHorizon(Unknown Source)
at java.util.Scanner.nextLine(Unknown Source)
at ServerSendingThread.run(ServerSendingThread.java:38)
Dann mach folgendes: Erstelle noch vor der KleinerServer()-Methode ein ArrayList so wie einen neuen Thread, der das ArrayList übergeben bekommt und nichts anderes tut als von einem Scanner einzulesen. Innerhalb der KleinerServer() Methode nimmst du wie gehabt die Clients entgegen und fügst sie in das ArrayList ein. Der vorher erzeugte Thread ließt nun vom Scanner ein und übergibt die Eingabe an alle im ArrayList vorhandenen Clients. Insofern benötigt deine Client-Klasse eine entsprechende send()-Methode, die du im Thread aufrufen musst. Wenn der Server nur dazu dient, den Clients von sich aus Nachrichten zu schicken, dann brauchst du nicht für jeden Client einen Thread, lediglich die entsprechenden Objekte (OutputStreams).
Ich hoffe du verstehst wie ich es meine.
Das musst du etwas anders anpacken.
Dein Server verwaltet alle Clients in einer Liste. Du sagst deinem Server dann, dass er eine Nachricht an alle Clients senden soll.
Die Benutzereingabe erfolgt dann in ner separaten Klasse.
Ok.
Jetzt hab ich glaub ich mehr Fragezeichen als vorher.
Wo starte ich meinen ServerSendingThread?
Ist mit Verbindungsanfragen annehmen server.accept() gemeint?
Was bedeutet das: // ClientHandler = ...; //clients.add(clientHandler);?
Ich habe gerade bemerkt, dass ich bereits die Möglichkeit habe mehrere Clients anzusprechen.
Ich muss den Befehl nur immer sooft eingeben wie es geöffnete Clients gibt.
Kann man das verhindern?
Also nochmal: Du benötigst eine Liste all deiner Clients, am besten ein ArrayList. Jeder hereinkommende Client wird darin gespeichert. Immer dann, wenn du einen Text in die Konsole eingibst, wird die Liste durchgegangen und jeder einzelne Client angeschrieben.
Wie du diese Idee nun umsetzt bleibt dir überlassen.
Das mit dem abspeichern in einer Liste sollte kein Problem darstellen.
Aber wie kann ich das mit dem Liste durchgehen machen?
Man kann ja nicht schreiben BufferedWriter.write("blabla").to(Alle Typen die in der Liste stehen).