Java Multiuser Chat hohe Systemauslastung

Status
Nicht offen für weitere Antworten.

PrinzMartin

Aktives Mitglied
Moin Moin

ich programmiere momentan einen kleinen Multiuser Chat hauptsächlich um son bisschen in Java drin zu bleiben. Ich habs momentan folgendermaßen gelöst:

Server wartet auf verbindung
Client meldet sich
Server speichert verbindung und startet eine Unterklasse (extends Thread) welche die ganze zeit auf Nachrichten von diesem Client wartet.

Funktioniert auch soweit ganz gut. Das Problem ist, dass die Threads meine CPU auslastung direkt auf 100% katapultieren. Meine Frage ist jetzt wie man das niedrig halten kann. (mein Pidgin wartet ja beim Chatten auch dauernd auf nachrichten und die CPU auslastung ist ziemlich gering ich denke beinahe gleich null.

Gibt es eine Lösung in der man entweder darauf verzichten kann für jeden Client einen Thread zu starten der den InputStream abhört oder kann man irgendwie den Thread auf kleine flamme setzen?

ich hoffe ihr wisst hilfe :)

Grüße
Martin
 

Marco13

Top Contributor
Das könnte ich da jetzt nicht einordnen. Sollte ein Versuch, zu Lesen, nicht automatisch bliockieren solange nichts da ist?
 

PrinzMartin

Aktives Mitglied
Ging die Frage an mich?

Ich weiß nämlich nicht genau was du hören willst :-D. ich hab auch noch nix ausprobieren können, da ich gerade mit dem PrintWriter dass problem habe, dass leerzeichenscheinbar als trennung angesehen werden. wenn ich also schreibe "hallo welt wie gehts" wird das als 4 nachrichten interpretiert.

aber der versuch zu lesen blockiert ja. deshalb brauch ich ja die threads. ich seh nur, dass die Anzeige für meine cpu auslastung beinahe nichts anzeigt (ich chatte über icq, gucke fern, etc) wenn ich aber auch nur einen java thread starte der irgend etwas dauernd macht oder dauernd auf etwas wartet geht die direkt auf 100%

Grüße
Martin
 

madboy

Top Contributor
Ähm... Du wartest aber nicht mit sowas?
Java:
while (true) {
  if(inputStream.read() != -1) {
    //irgendwas
  }
}
 

badmaxx

Mitglied
hab mich auch mal daran gemacht nen chat zu "bastel"
hab mich so in den grundsätzen an diese tutorial gehalten.
habe auch das problem das meine cpu auslastung auf 100% steigt.
in dem beispiel quelltext wird über while(true) auf eine neue verbindung gewartet.
mir fällt aber im moment auch keine andere möglichkeit ein. hoff mir kann jemand vom schlauch runterhelfen.
Danke im Voraus
 
T

tuxedo

Gast
Naja, wenn ich das richtig gesehen habe, dann wäre das die schleife hier:

Java:
while(true)
		{
			Socket client=listen.accept();

			connection c = new connection(this, client);
			connections.addElement(c);
		}

Da "accept" solange blockiert bis eine neue, eingehende Verbindung kommt, liegt da nicht das Problem.

Gibts da noch mehr solcher while-Loops? Wenn ja: Wie sehen die aus?

Tritt das Problem auch im Leerlauf (Server frisch gestartet, noch kein Client verbunden) auf?

P.S. Kannst ja auch mal in jede while-Loop ein "System.out.println("While XYZ");" einbauen. Dann siehst du welche Schleife sich zu tode läuft ... Alternative halt nen Debugger drauf ansetzen.
 
Zuletzt bearbeitet von einem Moderator:

badmaxx

Mitglied
so danke schonmal für die antwort.
hab jetz mal n System.out.println("...") in jede loop gepackt und festgestellt das ich keine endlos schleife hab.
Hab auch festgestellt das wenn ich den Server starte und n clients sich verbinden besteht kein problem.
Die CPU-Auslastung steigt erst wenn sich clients abmelden.
Hängt des evtl. damit zusammen das thread.stop(); deprecaded ist?
Irgendwie raff ich des nich was ich machen muss das ich den blöden thread stoppen darf.
 
G

Gast2

Gast
Irgendwie raff ich des nich was ich machen muss das ich den blöden thread stoppen darf.
Selbstmord der Threads

Java:
private boolean ende = false;
public void ClientThread()
{
    syso("Client erfolgreich gestartet");
    while(!ende)
    {
        // ...
    }
    // ...
    syso("Client hat sich verabschiedet");
}
public void Quit()
{
    ende = true;
    // ...
}

hand, mogel
 

badmaxx

Mitglied
des muss doch noch was einfacheres geben!
ich glaub einfach nich das ich mehr als 2 zeilen brauch um nen thread zu stoppen
 
T

tuxedo

Gast
Das ist das einfachste und zuverlässigste und nebenbei auch gängige Praxis.
Wobei: Die Loop von Mogel liegt im Konstruktur und nicht in der run() Methode... Wäre also so nicht ganz korrekt. Aber das Prinzip ist und bleibt das gleiche.


- Alex
 

PrinzMartin

Aktives Mitglied
oha so viele antworten :-D

also im leerlauf ohne verbundenen Client gehts auch schon hoch weil halt beim Server die besagte "accept" whileschleife die ganze zeit blockiert und wartet. Außerdem warte ich auch auf eingehende Nachrichten mit genau so einer while schleife. Kann man das denn irgendwie besser machen?
 
T

tuxedo

Gast
accept() blockiert. Das ist richtig. D.h. aber auch, dass die Schleife nicht mit 100% CPU Leistung sich im kreis dreht. Es wird gewartet bis ein Client kommt. Erst dann geht die Loop in die nächste Runde. Und das kostet (fast) keine CPU Zeit.

Poste doch mal deinen kompletten Servercode... (wenns nicht allzuviel ist). Dann kann mans direkt an der eigenen Maschine ausprobieren.

- Alex
 
T

tuxedo

Gast
Klar, so geht's auch. Ist doch aber nicht der gängige Weg, oder? Soll jetzt auch nicht Diskussionsgegenstand werden... Ging ja an sich um die Abbruchbedingung.

- Alex
 

PrinzMartin

Aktives Mitglied
Ah ich hab die endlosschleife gefunden.

while(!in.ready()) {}

wenn ich da ein Thread.sleep(1); reinsetze dann gehts. ich hab noch nich ganz kapiert wozu das gut ist aber man scheint es zu brauchen da ansonsten der server spinnt sobald ein client beendet wird.

Grüße
Martin
 

PrinzMartin

Aktives Mitglied
mhh mit Thread.sleep(1) hab ich keine CPU auslastung mit Thread.Yield() schießt die direkt hoch.

die stelle um die es geht sieht insgesamt im server so aus


Java:
public void run()
    {
      
      try {
      boolean fertig = true;
      in = new BufferedReader(new InputStreamReader(skt.getInputStream()));
      //out = new PrintWriter(skt.getOutputStream(), true);

      while(fertig)
      { 
        Thread.sleep(1); 
        
        while (!in.ready()) {Thread.yield();}
        
        data = in.readLine(); 
        System.out.print("Empfangen vom Client:   " + data);
        senden_an = hole_liste.getSktListe();
        senden_an.toFirst();
        while(!senden_an.isBehind())
        {
          skt = (Socket)senden_an.getItem();
          out = new PrintWriter(skt.getOutputStream(), true);
          out.print(data);
          out.println();
          senden_an.next();
        }
        
        System.out.println();
        System.out.print("Gesendet zum  Client:   " + data);
        System.out.println();
       
        //out.flush();

      }
      
      }
      catch(Exception e) {
         System.out.print("Fehler in cS_receive_thread    "+e);
         }	  	
    }


und der Client:
Java:
public void run()
    {
     try {
      boolean fertig = true;
      while(fertig)
      { 
        
        
        while (!in.ready()) {Thread.yield();}
        data = in.readLine();
        jTa_Output.setText(jTa_Output.getText()+data+"\n"); 
        //System.out.print("Empfangen vom Server:   "+data);
        //System.out.println();
       
        }

      //in.close();
      }
      catch(Exception e) {
         System.out.print("Fehler in cC_receive_thread     "+e);
      }	  	
    }



Grüße
Martin
 
T

tuxedo

Gast
Meines erachtens ist die Implementierung und Abbruchbedingung mit "in.ready()" so nicht ganz korrekt..

Schau mal in die Doku zu readLine() ... Da steht, dass wenn "null" zurück kommt, das Ende des Streams erreicht ist. DAS solltest du also abfragen: "while(data!=null) {...}".

- Alex
 

PrinzMartin

Aktives Mitglied
also das basiert zum größten teil auf einem beispiel alles bin ich noch nicht durchgegangen.

deine Theorie bestätig, dass der server ohne dieses while die ganze zeit "Null" empfängt und sendet sobald sich der client verabschiedet.

mhh klappt nicht. irgendwie empfängt der client dann nix mehr aber warum eigentlich nicht in.ready() laut doko:

public boolean ready()
Liefert true, wenn Daten zum Lesen aus dem Stream bereitstehen, so dass ein nachfolgender Aufruf von read() nicht blockiert, sonst false.

theoretisch müsste man das also einfach komplett weglassen können. Is mir ja egal ob das blockiert oder nicht. Dafür hab ichs ja in nen Thread gepackt

ich teste mal.
 
Zuletzt bearbeitet:
G

Gast2

Gast
der Server müsste bei readLine() in den blockierenden Modus übergehen ... also dort stehen bleiben bis etwas ankommt
 
T

tuxedo

Gast
Eben. Wenn "null" gelesen wird ist der Stream geschlossen, die Leitung tot und der Thread kann beendet werden. Und wenn ein Stream geschlossen ist, dann sollte readLine() auch nicht mehr blockieren ...

btw: Nicht alle Tutorials "draußen im Netz" machen's "richtig". Viele machen's "just make it work... somehow...". Also immer nochmal drüber schauen und bei unbekannten Methoden mal die JavaDoc konsultieren. Ist zwar Arbeit, aber man lernt doch einiges daraus.

- Alex
 

badmaxx

Mitglied
so hab mein problem zwar noch nich ganz gelöst und der werd ich auch nich mehr schaffen aber ich bin schon schlauer!
es hängt anscheinend mit dem appletviewer von java zusammen.
denn wenn ich das ganze in eine html datei einbinde funktioniert es ohne probleme!
wenn ich den viewer über den stoppbutton der IDE schließe gibt es auch keine problem nur wenn ich das ganze über das X in der ecke schließe spinnt er!

allerdings hab ich jetz ein anderes problem.
Ich will eine userliste einbinden was soweit ja kein problem ist, allerdings füllt er mir wenns im html eingebunden ist die liste nichtmal mit meinem eigenen namen(was er im viewer tut), dort fügt er aber auch nur einen namen ein! ich habe das gefühl das er für jeden thread eine neue List anlegt.

Server:
Java:
public static List users = new List();

public static List getUsers()
  {
    return users;
  }

public static void setUsers(List users)
  {
    chatserver.users = users;
  }

Client:
Java:
users = chatserver.users;
users.add("test");
chatserver.setUsers(users);

hab ich da irgendwo nen denkfehler drin?
 
G

Gast2

Gast
Java:
// public static List users = new List();
private static List users = new List(); // private - weil Member

public static List getUsers() // Zugriff auf Member nur via Getter & Setter
  {
    return users;
  }

// unnötig
// public static void setUsers(List users)
//  {
//    chatserver.users = users;
//  }

Java:
// users = chatserver.users;
// users.add("test");
// chatserver.setUsers(users);
ChatServer-Klasse.getUsers().add("test")
auf statische Methoden greift man über den Klassennamen zu ... nie über Instanzen

hand, mogel
 

badmaxx

Mitglied
hab das ganze grad mal ausprobiert und irgendwie will des aber immer noch nicht.
also entweder war mein urlaub zu lang oder zu kurz
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Einfacher Multiuser chat in java Netzwerkprogrammierung 18
D HTTP Apache-HttpClient/UNAVAILABLE (java 1.4) Netzwerkprogrammierung 18
M JAX-WS unter Java 17 plötzlich nicht mehr möglich Netzwerkprogrammierung 5
K Java RMI bricht ab wenn Remote eine Methode ausgeführt werden soll Netzwerkprogrammierung 5
M HTTP Let's Encrypt und Java Trust-Store Netzwerkprogrammierung 6
JaXnPriVate Java HTTPS Server (Secure Sockets) Netzwerkprogrammierung 15
Tobero Java serversocket nicht nur zuganglich für localhost Netzwerkprogrammierung 6
D path-Variablen in eine URL hinzufügen mit Java 1.8 Netzwerkprogrammierung 2
D WebSocket Server mit HTML Client und Java Server Netzwerkprogrammierung 5
S Von Java auf passwortgeschützten Server zugreifen + Umgang mit Ports Netzwerkprogrammierung 28
S Probleme bei Java-Installation auf Server (Linux/Shell/Terminal) Netzwerkprogrammierung 6
S Java: Anbindung an einen realen Server? (+ Portfreigabe) Netzwerkprogrammierung 8
H Socket Chat entwickeln mit Java Server Client Netzwerkprogrammierung 4
x46 Java SSLContext erstellen mit SSL-Zertifikat Netzwerkprogrammierung 1
P Jenkins Login per Java Download Manager Netzwerkprogrammierung 15
N Java socket Programmierung Filme verschicken Netzwerkprogrammierung 20
S HTTP Post?!? - Java Server Netzwerkprogrammierung 7
F Verbindung zu einem LDAP Server über Java Netzwerkprogrammierung 4
K Java Websocketserver Problem | Android to Pi Netzwerkprogrammierung 1
R Anfängerbeispiel: Suche Java-Anwendung die http-Anfragen in Tomcat liest Netzwerkprogrammierung 8
V Browsergame mit Java(WebSocketServer) als Backend? Netzwerkprogrammierung 5
platofan23 Socket Java Socket mit DynDns nicht erreichbar Netzwerkprogrammierung 6
S Fragen zu Java Webservice mit Axis2 Netzwerkprogrammierung 0
M Mit Java Mail Mails an Webmailer schicken Netzwerkprogrammierung 1
mor16Euro HTTP Php website mit Java aktualisiern Netzwerkprogrammierung 6
T HTTP JAVA Browser Konsolenanfrage(JavaScript) Netzwerkprogrammierung 7
L Socket Wie kann man in Java die Anzahl der Objekte in einem InputStream sehen ohne ihn durchgehen zu müssen Netzwerkprogrammierung 1
M Socket Verbindung Matlab(Server) Java(Client) Netzwerkprogrammierung 1
M Socket peer to peer Verbindung zwischen Java und Matlab Netzwerkprogrammierung 0
L Remote Desktop per Java steuern Netzwerkprogrammierung 4
F Server für Java Applikationen Netzwerkprogrammierung 16
J Webserver mit Java schreiben? Netzwerkprogrammierung 4
D JAVA RMI Netzwerkprogrammierung 1
K HTTP Mit Java HTML Codeauslesen um damit zu arbeiten Netzwerkprogrammierung 7
V Kann man mit Hilfe eines Java-Programms den Zugriff auf bestimmte Internetseiten verhinden? Netzwerkprogrammierung 3
J HTTP [Java 9] Neuer HTTP Client - Tutorial Netzwerkprogrammierung 3
T Mikrofonaudio über Java Server an Webbrowser streamen Netzwerkprogrammierung 13
A Bestimmter URL/Certificate per Java immer vertrauen (Trustmanager/HostnameVerifier) Netzwerkprogrammierung 1
T VPN-Verbindung über Java Netzwerkprogrammierung 4
M HTTP PATCH Request mit Java ausführen Netzwerkprogrammierung 2
Niggo_ Probleme mit Java Mail Netzwerkprogrammierung 14
Aruetiise Socket Java Programm auf Server Netzwerkprogrammierung 3
L FTP Java Interpreter unterbindet SSL Handshake Netzwerkprogrammierung 2
C IFrame mit java auslesen Netzwerkprogrammierung 1
A FTP wie kann ich von java auf datei in fpt://192.168.178.1 lesen/schreiben? Netzwerkprogrammierung 3
C Datensammlung mit Java RMI Netzwerkprogrammierung 0
K Java Jsoup : OnLoad Netzwerkprogrammierung 0
S Java Chat Server Netzwerkprogrammierung 8
Carres HTTP Vorhandenen Session-ID Cookie von Firefox, Chrome oder IE in Java verwenden Netzwerkprogrammierung 2
B Java+Grbl: G-Code Befehle mit Java an Arduino senden und lesen Netzwerkprogrammierung 1
Z HTTP HTML Element auslesen in Java Netzwerkprogrammierung 1
T Socket Java Programm hängt sich auf bei dem versuch von einem Socket scanner Daten zu erhalten. Netzwerkprogrammierung 1
Thallius HTTP HTTPS unter Java 1.6 schlägt fehl Netzwerkprogrammierung 4
Thallius Java Application über ZScaler benutzer? Netzwerkprogrammierung 0
P Chat in Java Netzwerkprogrammierung 3
C java.net.ConnectException: Operation timed out? Netzwerkprogrammierung 2
M Java Eingabe auf FTP Server übergeben Netzwerkprogrammierung 4
T curl request in java umwandeln Netzwerkprogrammierung 4
M Socket Java Server: NullPointerException Netzwerkprogrammierung 4
J Java Server empfängt php inhalt nicht Netzwerkprogrammierung 1
I Socket Kommunikation C / Java Netzwerkprogrammierung 2
H Machbarkeitsfrage: TCP/IP Client (z.B. Netty) für Java Web Applcation Netzwerkprogrammierung 1
L Java RMI Objekt konsistenz Netzwerkprogrammierung 1
H Portforwarding umgehen in Java? Netzwerkprogrammierung 5
D Response in Java Servlet erzeugen Netzwerkprogrammierung 0
X Mit Java eine Applikation auf einem anderen Windows Rechner (Windows Server 2008) starten Netzwerkprogrammierung 1
E HttpUrlConnectionExample cannot be resolved to a type / Java 8 Netzwerkprogrammierung 1
F Socket Java Server mit Android App, Antwort vom Server an App Netzwerkprogrammierung 5
M Java-Programm aus dem Web laden Netzwerkprogrammierung 3
S HTTP-Requeste von Browser mit Java sniffen? Netzwerkprogrammierung 9
J access denied (“java.net.SocketPermission”…) mit Java 8 Netzwerkprogrammierung 1
N CURL requests in Java Netzwerkprogrammierung 6
P Kritische Java-Anwendung und Citrix veröffentlichen Netzwerkprogrammierung 1
F Java Server Scanner oder InputStream kann nicht gelsesen werden! Netzwerkprogrammierung 6
1 Netty NIO oder Java IO Netzwerkprogrammierung 2
1 Via Java mit WLAN Netzwerken verbinden Netzwerkprogrammierung 5
J Java Service Wrapper Netzwerkprogrammierung 1
K Mit Java ASPX Webseite fern steuern Netzwerkprogrammierung 2
H Socket Java | Server sendet Nachricht nur wenn vorher eine JOptionPane-Nachricht ausgegeben wurde. Netzwerkprogrammierung 2
K Emailsenden via Java Applikation Netzwerkprogrammierung 5
L Mit Java über PHP in MySQL anmelden (Login script) Netzwerkprogrammierung 3
C Java Chat Admin Kenzeichnung Netzwerkprogrammierung 14
P PHP Script per Java ausführen Netzwerkprogrammierung 2
P PPTP Protokoll für JAVA Netzwerkprogrammierung 14
T php/java-bridge Netzwerkprogrammierung 16
D Webseite(mit JavaScript-Element) mit Java auslesen Netzwerkprogrammierung 0
G Multiple Clients and one Server --> java.lang.NullPointerException Netzwerkprogrammierung 1
E Java Server übers Internet erreichen Netzwerkprogrammierung 4
D Socket Error: java.lang.NullPointerException Netzwerkprogrammierung 1
windl AirPlay mittels Java Netzwerkprogrammierung 0
R Email mit Java API Netzwerkprogrammierung 1
P Java Deauth / Deauthentication request Netzwerkprogrammierung 10
F Socket Java - Server/Client simple Netzwerkprogrammierung 1
E HTTP java.lang.IllegalArgumentException: protocol = http host = null Netzwerkprogrammierung 1
R Java - Socketprogrammierung Netzwerkprogrammierung 10
B Methoden und Konstruktoren von Java.net package werden nicht geladen Netzwerkprogrammierung 2
L Email versenden mit Java funktioniert nicht, Fehlermeldungen: MessagingException & SocketException Netzwerkprogrammierung 10
V Templates für Java Client rabbitmq Netzwerkprogrammierung 4
N Socket java.net.ConnectException Netzwerkprogrammierung 5
A Java Server - IOS Client Applikation Netzwerkprogrammierung 20

Ähnliche Java Themen

Neue Themen


Oben