# Socket - Verständnisproblem



## Samuel (16. Mai 2006)

Hallo,

wir haben angefangen mit Sockets zu arbeiten um Client Server Verbindungen zu erzeugen.
Dies klappt soweit ganz gut, der Server lauscht auf nem Port und wenn da was ist, erzeugt er ein Thread mit dem Objekt.

Wie gesagt, läuft einwandfrei, was ich allerdings nicht verstehe:
Sagen wir ich will einen Chat programmieren.

Server befindet sich in einer unendlichen Schleife, wo er am ServerSocket Objekt auf den spezifizierten Port guckt, ob jemand da ist.
Sowohl Client als auch Server haben ihre Output und Input Streams, nun aber zum Problem: Es sind 3 Clients verbunden und sind doch per default doch im Output Modus, oder? Die Clients erwarten vom Server doch Text, der von anderen User kommt.
Wie kannder Server nun überhaupt was schicken, wenn er nur am ServerSocket auf die .accept() guckt?
Noch ein Problem, wie kann ein Client denn eine Nachricht tippen und senden, wenn der Client doch im Output Modus ist.

Ich habe Probleme zu verstehen, wie ein Client die Zustände wechselt, es kann ja sein, dass Client im Output Modus auf Nachrichten vom Server wartet und es kommt keine und der Client tipp was, hängt aber doch in der .readLine solange fest, bis Server was sagt.

Und das gleiche Problemist beim Server ja auch, alle Clienten sind im OutputModus jedoch ist der Server im Input Modus, hat aber nichts zu sagen.

Noch was: Der Wechsel der Zustände, von Output zu Input, wie gelingt er so, dass der Server etwas an den Client sendet und der sicherstellt, dass der Client auch hinhört?

Wenn Server
Output
Input 
macht,
muss der Client ja beim Server Input im Output sein,  da aber die Clienten threaded sind, kann doch sein, dass der Client garicht bereit ist?

Diese Socket Sache ist verdammt unklar für mich


----------



## Illuvatar (16. Mai 2006)

accept() liefert ja einen Socket zurück. Normalerweise wird man das so machen, dass man für jeden Client einen neuen Thread erstellt, in dem an dem Socket gelesen wird. Falls man in den Socket schreiben muss, ist das ja normalerweise in einem anderen Thread. Dann kannst du also in dem anderen Thread in den Socket schreiben, während der Clientthread liest.

Also am Beispiel Chat:
[table:59dfd74993][tr:59dfd74993][td:59dfd74993]
*Server* hat
*Thread 1*: accept()
Wenn was accepted wird, startet er einen
*Clientthread*. Der lauscht und wenn er etwas kriegt, schreibt er das in alle Sockets.
[/td:59dfd74993][td:59dfd74993]
*Client*
hat die Verbindung zu dem Server in einem Socket. In einem Thread lauscht der da. Wenn in der UI etwas eingegeben wird, wird aus dem EDT die Nachricht an den Server geschickt.[/td:59dfd74993][/tr:59dfd74993][/table:59dfd74993]


----------



## Samuel (17. Mai 2006)

Wie kann denn ein Client, der Lauscht seinen Zustand ändern?
Wenn dert Client lauscht, sieht das ja so aus, dass er aus dem BufferedReader und dem Inputstream des Sockets eine 
.readLine(); aufruft und an dieser Stelle so lange hängen bleibt, bis readLine auch wirklich was tut, wie kann ich denn einen Clienten da raus holen und ein println erzeugen?


----------



## LordSam (17. Mai 2006)

Du kannst an einem InputStream abfragen ob überhaupt Daten anliegen, so das der aktuelle Thread nicht geblockt wird und was anderes machen kann:


```
int bytesAvailable = inputStream.available();
```

Im Prinzip machst Du jetzt eine Schleife, die solange läuft wie keine Daten anliegen. In der Schleife solltest Du dann deine "Ausgangsqueue" verarbeiten und ansonsten den Thread eine weile "schlafen" lassen (Thread.sleep(..)), damit du nicht unnötig CPU Zeit vergeudest.


----------



## Samuel (17. Mai 2006)

Das klingt gut, danke 
Ok, ich frage immer ab, ob was vorliegt, jedoch verstehe ich nicht, wie ich das Abfragen durch das senden unterbrechen kann.
Oder prüft man in nem thread ob bytes im Input liegen und danach vielleicht ob bytes in einem Output Pool liegen? Also das eintippen von Text erzeugt keinen println sondern das füllen einen Strings oder ähnliches und die send/read routine guckt nach, ob da was drin ist und sendet es ggf?


----------



## KSG9|sebastian (17. Mai 2006)

Lies dir mal das durch: http://www.java-forum.org/de/viewtopic.php?t=6033&highlight=chat

Da ist alles schön erklärt und sogar noch ein Beispiel von nem Chat drin.


----------



## Illuvatar (17. Mai 2006)

Ich glaub du verstehst da was falsch... da gibt es nicht irgendeinen Zustand den du ändern musst. Während der eine Thread readLine macht, kann ein anderer write aufrufen.


----------



## Samuel (17. Mai 2006)

Danke, guck ich mir an


----------



## Samuel (20. Mai 2006)

Habs mir mal genauer angeguckt und habe bis jetzt drei Anmerkungen.

ServerBody benutzt ja die Methoden der Sever Klasse, broadcast usw, wie kann das funktionieren, wenn Server doch durchgehend in der while Schleife hängt und lauscht?
Führt er dennoch Methodenaufrufe auf? Wie, wenn es ken thread ist?

Und ist das Übergeben  der Server Referenz an die einzelnen Verbindungen nicht schlechtes OOP? Ich kenne auch keinen besseren Weg, aber ist es nicht ziemlich ungeschickt den Verbindungen deren Inhaber zu geben?

Und wie funktioniert denn der Client, wenn er ewig in der readLine Schleife hockt, ich kann dann doch nichts senden, oder?


----------

