# Einfacher Multiuser chat in java



## St@TiC (14. Jan 2004)

hallo
ich möchte nen total simplen multiuser chat in java schreiben. mit nem server und nem client grafische oberflaeche und das ganze schöne drumherum ist nicht notwendig. auf konsolen basis reicht aus.

leider hab ich keinen blassen schimmer wie ich das anstellen soll. weiß einer zufällig ein gutes (wenn möglich deutschsprachiges) tutorial wie man sowas macht?
oder zumindest ein gutes nachschlagewerk das socketprogrammierung in java betrifft. damit ich u.u mit viel glück und rumprobiererei was zu stande krieg.

bin für jede hilfe dankbar


P.S. spart euch die antworten "wenn du neuling bist beschäftige dich mit leichteren sachen als  gleich mit nem chat"
der meinung bin ich auch aber erklärt das meinem ausbilder, der mir das als übung aufgetragen hat


----------



## sigma (14. Jan 2004)

ich würde es am einfachsten mit udp machen. falls du es noch nie gemacht hast und ein kleines beispiel willst dann kann ich dir ein schicken.

der client schreibt was am server. der server schickt dann per udp eine message das es neue nachrichten hat. die client holen sich das selbständig alles vom server

gruss sigma


----------



## erdbeerbunny (14. Jan 2004)

Hallo,

ich schlage häufig Themen im Buch "Handbuch der Java-Programmierung" von Guido Krüger nach. Das Buch gibts unter www.javabuch.de auch kostenlos als HTML-Version... Da gibts ein eigenes Kapitel Netzwerkprogrammierung mit Beispielen von Client/Server-Programmen... Ich persönlich finds auch einfacher, wenn der Server eingehende Nachrichten einfach an die angemeldeten Clients weiterleitet... Ob Du UDP oder doch TCP benutzt, klannst Du ja immernoch entscheiden  :wink:


----------



## Kerberus (14. Jan 2004)

Bin auch gerade am programmieren eines Chat-Programmes. Ich habe eine Socket-Verbindung aufgebaut zum anderen Client, doch geht das nur durch eine IP. Leider sind die meisten IP's heute dynamisch. Wie kann ich das Problem lösen. Bis jetzt funktioniert mein Chat nur im Intranet.


----------



## Stefan1200 (14. Jan 2004)

Gerade mit der Multiuser Geschichte habe ich Probleme. Wie macht Ihr das? Ich bekomme immer nur ein Chat zwischen zwei Leuten hin. Ich bekomme das Server seitig nicht hin, das der Server bei einer einkommenden Nachricht die Nachricht an die anderen Clients weiter sendet. Habt Ihr da mal denkanstöße oder kleine Beispiele für mich?


----------



## sigma (14. Jan 2004)

hab au mal einen chat bzw. einen messenger programmiert.

habe es so gelösst, das ich einen server gemacht habe. alle haben sich auf dem server eingeloggt. so habe ich die ip von den client bekommen. sobald sich ein client eingeloggt hat, habe ich allen onlineclients die ip mitgeteilt. wenn jetzt jemand z.b. a mit b komunizieren möchte, so kennen sie sich gegenseitig weil ich ja die ips der beiden verschickt habe.

gruss sigma


----------



## nekton (15. Jan 2004)

ich wuerde eine "broadcast" variante vorschlagen. du programmierste einen server der die verbindungen annimmt. diese werden ja im grunde genommen wie filestreams gehalndelt.  also braucht man eine logik/klasse die alle filestreams auslist bzw. eine nachricht an alle anderen filestreams sendet.


```
+---------------------+      +--------------+     +---------------------+    /               \       +-----------+
|  SocketStream N  | -----|    Logik        |----|  SocketStream M  |---   Netzwerk    --- | client M    |
+---------------------+      +--------------+     +---------------------+    \               /       +-----------+
            |
            |
           ________
         /               \
        |NETZWERK|
         \________/
            |
            |

+------------------+
| Client N            |
+------------------+

1. client verbindet sich mit socket
2. bei anfrage erstellt der server einen object "SocketStream", welches eine verbindung zur logik
    klasse "Logik" hat.
3. client sendet nach erfolgreicher verbindung den text "foobar" an den Server.
4.  SocketStream empfaengt "foobar" und leitet den eingegangenen text an die Logik.
5. die logik sendet den text an jeden seiner clients
```

ich weiss nicht ob das jetzt richtig ruebergekommen ist, aber wichtig ist es bei diesem model, das jeder serversocket seine angaben an eine zentrale instanz weitergibt, welche wiederum jeden einzelnen socket mit den entsprechenden daten (in richtiger reihenfolge) versorgt.

das model ist recht grob und ungepfeilt, aber es soll nur den etwaigen ablauf verdeutlichen.


----------



## Stefan1200 (15. Jan 2004)

nekton hat gesagt.:
			
		

> ich weiss nicht ob das jetzt richtig ruebergekommen ist



Leider habe ich das jetzt nicht verstanden. Wie laufen deine Clients denn?
Jeder Client läuft in einem eigenen Thread?
Wenn ja, wie komme ich dann an diese Thread wieder heran?
Ich kann ja nicht von jeden Client eine instanz speichern, oder muss ich das?
Ich stelle mir jetzt ein Server mit 10000 Client vor, ich kann ja nicht 10000 Input/Output Streams oder Threads speichern, oder? Jedenfalls klingt das nicht gerade performant.


----------



## Kerberus (15. Jan 2004)

An Sigma: Wie kriegst du die IP? Gibt es einen Java-Befehl der das kann?
Ich habe zwar ein Programm geschrieben um die IP zurück zu liefern, aber es gibt immer 127.0.1 aus, egal auf welcher Maschine. 
Es stellt sich auch noch folgendes Problem. Die meisten User habe heutzutage einen Router, so auch ich. Wie kann ich die IP von einer Person erfahren wenn diese hinter einem Router sitzt.


----------



## odysseus (15. Jan 2004)

ein tut:

http://java.seite.net/chat/


----------



## Roar (15. Jan 2004)

@kerberus:

```
Enumeration ifaces = NetworkInterface.getNetworkInterfaces();
while (ifaces.hasMoreElements())
{
    NetworkInterface ni = (NetworkInterface)ifaces.nextElement();
    if(ni.getName().equals("ppp0"))
    { // für ppp
        Enumeration addrs = ni.getInetAddresses();
        while (addrs.hasMoreElements())
        {
            InetAddress ia = (InetAddress)addrs.nextElement();
            System.out.println("Host: "+ia.getHostName());
            System.out.println("IP: "+ia.getHostAddress));
        }
    }
}
```
ich hab auch lange gebraucht um das rauszukriegen

@edit: Code besser lesbar gemacht / Stefan1200
@edit: War ja auch nur schnell aus meinem Webserver kopiert, sorry  / Roar


----------



## Stefan1200 (15. Jan 2004)

odysseus hat gesagt.:
			
		

> ein tut:
> 
> http://java.seite.net/chat/



Das Ding sieht ganz interessant aus, danke dafür.


----------



## St@TiC (16. Jan 2004)

ok ich werde mich jetzt erstmal etwas dran setzten war die letzten tage etwas verhindert.
java-buch.de da will mein rechner ne datei downloaden aber net die seite anzeigen...
ich sag schonmal danke für die hilfe


----------



## nekton (16. Jan 2004)

Stefan1200 hat gesagt.:
			
		

> Leider habe ich das jetzt nicht verstanden. Wie laufen deine Clients denn?
> Jeder Client läuft in einem eigenen Thread?



so gesehen /und tatsaechlicher weise ) ja, da der "client" ein eigenes programm darstellt, welches (in der regel) auf einem ganz anderen system laeuft . der browser ist ein client und der server wo das java-forum drauf liegt eben der server der sockets haendelt und die logik dahinter die die daten rausrueckt (vereinfacht gesehen).



> Wenn ja, wie komme ich dann an diese Thread wieder heran?
> Ich kann ja nicht von jeden Client eine instanz speichern, oder muss ich das?



die hast  in der logik (dessen instanz genau einmal existiert) ein array/vector/liste von socketverbdingunen, die eingehende informationen an die logik weiterleiten. diese schreibt dann die daten an jede "verbindung" die sich in der liste befindet.




> Ich stelle mir jetzt ein Server mit 10000 Client vor, ich kann ja nicht 10000 Input/Output Streams oder Threads speichern, oder? Jedenfalls klingt das nicht gerade performant.



es gibt sicherlich andere ansaetze, aber im endeffekt ist das das schicksaal eines echtzeit-servers. jeder client sollte (solange es eine globale nachricht ist) ueber die selben daten verfuegen. also muss die logik ueber die liste loopen und jedem einzelnen infomationen schicken.

ich koennte mir da allerdings andere ansaetze denken, so wie einen message cache, der ganz nach datenbank manier auf angfrage, alle vorhandenen nachrichten eines zeitraums wiedergibt. aber das hat unter umstaenden nicht viel von wirklicher echtzeit.

bisweilen wenn man 10000 clients haendeln soll, stellt sich mir da allerdings die frage, ob man dann nciht lieber einen "clusterfaehigen" service programmieren sollte. das sieht bei den kollegen in den irc netzen auch nciht anders aus denke ich. das ist schon ein verdammt hohes datenvolumen das es dort zu bewaeltigen geht, und wenn ich erlich sein soll, denke ich das dabei ein normales 100 MBit netzwekr auch so langsam probleme bekommen wuerde, da die frequence einfach zu hoch waere.

wohingegen wenn man dieses clustering betreiben wuerde, und pro server z.b. 99 clients + 1 serververbindung legt sich die lage doch entspannen wuerde.

mir wuerden diverse ansaetze einfallen aber der obige ist einfach der trivialste


----------



## nekton (16. Jan 2004)

Stefan1200 hat gesagt.:
			
		

> odysseus hat gesagt.:
> 
> 
> 
> ...




```
for (i=0; i<connections.size(); i++)
	{
		you = (connection) connections.elementAt(i);
		you.out.println(msg);
	}
```

btw. ist das auch nciht sehr viel anders, als ich oben versucht habe zu erklaeren


----------



## Stefan1200 (20. Jan 2004)

nekton hat gesagt.:
			
		

> ```
> for (i=0; i<connections.size(); i++)
> {
> you = (connection) connections.elementAt(i);
> ...



Hmm, genau diese Zeilen mit dem Typecasting werfen bei mir ein StackOverflowException. Hat jemand eine Idee?


----------



## HeyMan (21. Jan 2004)

Es kommt vielleicht etwas spät, aber ich würd das alles mit Servlets (Serverseitig) und Http(s)Connection (Clientseitig -Applet/Applikation) machen. Vorteil: Ich kann auch über Firewalls hinaus kommunizieren und ich habe bereits ein spezifiziertes Kommunikationsprotokoll auf dem ich aufbauen kann.
Ablauf:
Auf dem Client läuft ein kleiner Thread, der das Servlet alle ??? milliseks per get abfrägt.
Das Servlet liest bei post request die mitgelieferte message (meine chateingabe) ein und speichert sie in einem log-file.
Dieses logFile wird vom Servlet als ausgelesen und verschickt, bzw. kann auch als File direkt verschickt werden und die Applikation liest dann die Zeilen aus..... je nach Performance kann man es ja so oder so machen.




WebServer <-----PORT 80/443-------<---GET-------       
....SERVLET ---------RESPONSE (logfileinhalt)---------> APPLIKATION 
.......|...................................................................   Thread -> GET     
...... |                    
...... | <-----<POST (Message) ---------------------------                      
...... |FileIiOutputStream
...... |---------- RESPONSE (neuer logfileinhalt) ------>
   LogFile
-------------                                                                                


gruß heyman

PS:_ sorry...wie gesagt ist vielleicht etwas spät.


----------



## desert pinguin (21. Jan 2004)

Sicher bin auch zu spät. Ich würde eine JavaSpaces-basierte Architektur vorschlagen.


----------



## cello (19. Feb 2004)

Hallo,

es gibt eine API die das SIP implementiert (Session Initiating Protocol). Für die Programmierung des Clients kann man die JAIN-Implementierung benutzen. Als Server kann man den SER (Sip Express Router) benutzen.
Ist vielleicht etwas mühselig sich da einzuarbeiten, aber wenn man sich ernsthaft mit IM oder VoIP beschäftigt, lohnt es sich auf jeden Fall.

Viel Spaß, (V\arcel

API/JAIN

Jain-Implementierung

Server

SER


----------

