Socket kein "aktives warten"

Moin!

Wenn man eine Verbindung zwischen Server und Client bereits bestehen hat und Daten verschicken will (BEIDSEITIG), dann kann man das ja im einfachsten Weg durch eine while Schleife realisieren, immer gucken ob Daten anliegen und dann ggf abholen.
Aber das resultiert logischweise in einer CPU Auslastung von 100% was ja nunmal nicht gerade optimal ist. Geht das nicht auch mit Events oder sowas, damit man dann diese Auslastung nicht hat?

Beispiel:
Java:
while(!con.liegenDatenAn()){
				
			}
tuWasMitDaten();

Das sollte doch irgendwie mit Listenern und Event klappen oder ist das per Netzwerk nicht möglich?
Es muss ja irgendwie gehen, sonst wärs mir kaum möglich mehrere Programme im Internetzugriff parallel laufen zu lassen :D
Auf Threads würde ich gerne verzichten, wenns nur so geht, bitte ein bißchen erklären, ich komm damit nicht zurecht, besonders was die deprecated Methoden angeht, dann weiß ich nciht was ich nach start() machen soll ^^

Wär nett wenn hier jemand ein paar brauchbare Vorschläge machen könnte ;)
 
T

tuxedo

Gast
Sofern du nicht NIO verwendest hast du "blocking IO".
Das heisst, ein
Code:
read()
jedweder Art wartet bis Daten vorhanden sind. Eine "durchrasende endlosschleife" ist hier i.d.R. gar nicht möglich (außer du fängst an timeouts zu setzen oder so).

Lass mal etwas mehr Code sehen. Denn so kann ich mir das gar nicht erklären... (unter der vorraussetzung dass du nicht sonstwo eine Endlosschleife verbaut hast).

- Alex
 
S

SlaterB

Gast
Das sollte doch irgendwie mit Listenern und Event klappen oder ist das per Netzwerk nicht möglich?
wenn es einen Listener gäbe, dann muss irgendjemand diesen aufrufen, dieser jemand wäre es dann der per while-Schleife dauernd nachguckt usw.,
das Problem wird nur verschoben, es kann prinzipiell nicht gelöst werden,
Thread.sleep() in der Schleife ist wirklich das, was die Systembelastung auf 0,0x% runterfährt


zum Vergleich: bei der Mauseingabe ist es letztlich der Sensor in der Maus, der dauerhaft aktiv ist,
niemand sagt dem Bescheid, der muss ständig oder alle x ms nachschauen, wie die aktuelle Position ist,

ok, zum Teil ungünstiges Beispiel, da die Maus eh auf 100% läuft oder laufen könnte, da mit eigener 'CPU'/ geringerem Schalttakt ausgestattet
 

Kr0e

Gesperrter Benutzer
Oh, oh, oh.... Das sind ja eine Menge Fragen und Erwartungen.

Threads sind nichts magisches in Java... Es gibt wirkliche viele einfach zu verstehende Tutorials im Internet.Selbst wenn ich Lust dazu hätte, würd ichs heir nicht besser erklären können...

Was deine Hauptfrage angeht:

Nein!, man schaut nicht 1000x pro Sekunde nach ob was da ist und macht weiter wenn nicht und schaut dann wieder...

Das einfachste Konzept funktioniert nur in Verbindung mit Threads was aber wirklich kein großes Ding ist.
Undzwar klappt das so, dass du sagst read() und diese Methode blockiert genau solange, bis was da ist.
Deswegen auch Threads... Blockieren heißt dein Programm würde mit einem Thread an dieser Stelle einfach eiskalt aufhören bis was da ist....

Es gibt da noch bessere und neuere Ansätze (Obwohl mal ganz nebenbei, ich weiß gehört grad nicht dazu: Die Funktion select bei BSD Sockets gibt es doch seitdem es Sockets gibt (C z.b.), warum macht Java den ganzen Firlefanz mit NIO und vorallem so verspätet! NIO gibts doch erst seit 1.4.2 oder so... Und "select" schon seit Jahren :D, Egal zurück zum Thema)

Also diese besseren Ansätze sind, wie ich grad gesagt hab, z.b. durch NIO implementiert. Zusammengefasst: NIO verwendet
einen Selector der aufpasst, wo was geschieht und dir bescheid sagt, wenns was zu machen gibt. Du bräuchtest theoretisch nur einen Thread dafür im kleinen Stil. Allerdings ist eigenes NIO Client/Server System recht haarig. Nimm dazu (Wenn du es denn wirklich nehmen willst am Anfang) am besten ein OpenSource Framework wie z.B. Apache Mina...

Fazit: Versuchs erstmal mit Sockets in Verbindung mit Threads....
Google ist eine perfekte vor Antworten sprudelnde Quelle...

Gruß,

Chris
 
T

tuxedo

Gast
Mir scheint ihr habt alle diesen Satzteil des TS übersehen:

immer gucken ob Daten anliegen und dann ggf abholen.

Bei IO (und ich nehm stark an dass er kein NIO benutzt wenn er mit Threads nicht sehr zurecht kommt), muss man "gucken und abholen" nicht in zwei Schritten machen. Man macht einfach ein [c]read()[/c], welches glücklicherweise blockiert BIS Daten anliegen.

Damit ist die CPU-Last im Keller und nicht bei 100%. [c]sleep()[/c] kann man sich dann ebenfalls sparen.

Also, Beispielcode her, sonst ist alles rätselraten wohlmöglich für die Katz ..

- Alex
 
client:
Java:
while(true){
            while(!con.liegenDatenAn()){
                
            }
            //sozusagen eine Sperre... nciht wirklich schön, aber sonst hab ich NPE wenn ich drauf zugreife
            tuWasMitDaten();
}

con.liegenDatenAn() bedeutet eigentlich nichts anderes als
(socket.getInputStream().available() > 0)

Wär dann wohl besser beim benutzen des Objekts einfach vorher abzufragen ob das dann nicht null ist oder?

Die Serverseite ist genau so implementiert, nur, dass diese mit einem array von Connections (sockets + ein paar zusatzinfos) arbeitet.

Danke für eure Antworten! Das mit sleep hatte ich auch schon mal drin, aber ich habs wieder rausgenommen, fand ich halt einfach nciht schön, aber besser als das hier sicherlich :)

Das lesen des Objekts mache ich so:
Java:
ois = new ObjectInputStream(s.getInputStream());
			Object o = ois.readObject();
Ist das besagtes read?

Also ich will ja nicht nur einmal ein Objekt verschicken, sondern einfach die ganze Zeit hin und her. Das verschickte Objekt wird von den einzelnen Clients bearbeitet (hintereinander), dann vom server zwischengespeichert und wieder an alle geschcikt, so dass dann der nächste loslegen kann ;)

Geht das dann auch ohne sleep oder komm ich da nicht drum rum?
 
T

tuxedo

Gast
Das lesen des Objekts mache ich so:
Java:
ois = new ObjectInputStream(s.getInputStream());
			Object o = ois.readObject();
Ist das besagtes read?

Jepp. Zum Bleistift. Ist dabei völlig egal ob du auf einem ObjectStream liest oder auf einem anderen. ein read() blockiert i.d.R.

Also ich will ja nicht nur einmal ein Objekt verschicken, sondern einfach die ganze Zeit hin und her. Das verschickte Objekt wird von den einzelnen Clients bearbeitet (hintereinander), dann vom server zwischengespeichert und wieder an alle geschcikt, so dass dann der nächste loslegen kann ;)

Geht das dann auch ohne sleep oder komm ich da nicht drum rum?

Wenn Ständig hin und her geschickt wird, brichst du dir mit Java IO ein Bein ab wenn du nur einen einzigen Thread benutzt. Ich kann nur empfehlen mindestens einen weiteren Thread hinzu zu ziehen. Beispiele gibts hundert tausende (wenn nicht sogar Millionen oder Milliarden) über Google, und zum großteil auch hier im Forum.

Google einfach mal nach "java multithreaded server".

Wenn du um's verrecken keinen weiteren Thread mit Java IO willst, dann wirst du wohl um ein sleep() nicht wirklich drum rum kommen.

- Alex
 
Vllt nicht ganz bis zur hinreichenden Bedingung, aber sicher bis zur notwendigen ;)
Habs mit sleep gemacht, funktioniert wunderbar.

Das Projekt ist halt doch sehr umfangreich und ich hab ja auch noch andere Sachen zu erledigen ;)
 

Ähnliche Java Themen


Oben